
Why I Don't Use The JVM - jshen
http://yakkstr.com/posts/5270-Why-I-dont-use-the-JVM
======
narrator
Yes, Java uses a lot of memory. It uses a lot of memory mostly because it
doesn't mmap static shared lib files. Most c library based systems (e.g PHP,
Python, Ruby) do. When the system can mmap read only shared lib files, that
uses a lot less memory because multiple processes can share them and they are
only read in to memory as they are accessed thanks to the page fault mechanism
of 386 protected-mode architecture.

Java can't do this because Java self-modifies code (JIT) to run faster while
it's running. Once all your classes are loaded into ram though, the memory
gets consumed at a much more leisurely pace. However, multiple apps can't
reuse each other's already mapped into memory code like they can with PHP,
etc. As far as appserver restarts, just pay the money for JRebel already and
quit complaining. Your life will be so much better.

~~~
t_hozumi
I cannot understand why JVM sticks to JIT. JIT's advantage is mainly
portability of intermediate code. So once intermediate codes are deployed in
server, I don't care whether pre-compile takes 30 minutes or not if memory
allocation and computation become more efficient. However this might be stupid
idea.

~~~
benjiweber
JIT allows a range of optimisations that are not possible with AOT
compilation. A JIT has access to more information at runtime such as profiling
data and so can perform more informed optimisations. It can also change over
the lifetime of the programme if observations change.

Some interesting stuff here
[http://wikis.sun.com/display/HotSpotInternals/PerformanceTec...](http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques)

------
suprgeek
The JVM is the one part of Java that is actually _Gaining_ more mindshare.
Granted "hello world" is not the ideal usecase - but you are missing the
point. The cost you pay for hello world still remains the same up to a
moderately sized app, and the more the complexity of your app, the more
benefits you start to see from the JVM's memory model.

A better comparison would be a real world app that scales to a number of users
- tell me about JVM memory usage and performance then.

------
theatrus2
The JVM (at least the Oracle/Sun version) has some scary seeming memory
allocation policies. One of the biggest offenders is its complete
unwillingness to ever shrink the system allocated memory, even if the heap is
95% empty. For instance, if your application has a huge peak allocation period
(whether your fault or an issue with soft references sticking about when you
really don't want them), it will put memory pressure on the OS for the rest of
its (process) life. If the JVM has an option of garbage collecting large
amounts of objects or growing the heap, it generally prefers growing the heap.
You can run quite a few Java applications with amazingly small heaps at
everything will be fine (except for performance due to GC overhead).

The abstraction breaker here is that your application often has a set of ideal
GC settings, which need to be set. You cannot forget about the garbage
collector when using the JVM.

------
cageface
Hello world and hobby projects are not the target for the JVM. It may take a
good chunk of RAM to fire it up at all but you can serve far more clients in
that same chunk than you could with the number of Ruby processes, for example,
you could run in the same memory. Look at how much more performance Lift/Scala
can squeeze out of the same box than Rails.

~~~
jshen
This is certainly true when you have to scale at some high level, but I think
that level is a lot higher than most people realize. I worked at
yellowpages.com for a while and we were serving a large amount of traffic (the
local ads on bing are from yellowpages) with native ruby. The JVM may have
been a better option at that scale, but the vast majority of sites won't reach
that scale. And ruby handled it just fine. The actual search logic was run on
the JVM though.

~~~
cageface
Sure, but the point is that the JVM makes you pay that memory cost up-front,
so it looks a lot more resource-heavy than it really is, whereas the scaling
cost of things like PHP and Ruby is back-loaded.

People worry about scaling too much in general, IMO, but you'll actually get
more mileage out of your hardware with something Clojure or Scala than you
will with Python/PHP/Ruby/Perl.

------
saryant
While I see his point regarding excessive memory usage WRT the JVM, I don’t
think this matters much. The fact is memory _is_ cheap these days and the
convenience of the JVM is something that’s tough to overlook. Furthermore,
while a Hello World app may require 100MB when implemented on the JVM, much of
that is overhead which will stay relatively constant as your process grows
more complex (to a point, obviously). I can run multiple processes on the same
JVM instance and stay within reasonable memory bounds.

Also, we need to consider the alternative. Where would we go if we didn’t have
the JVM? It’s not like .Net is much better in this regard. We could go without
a system as heavyweight as these two but then we lose all the advantages that
come along with that weight.

Certainly, those advantages are _not_ needed for a lot of purposes. Looking at
what he’s running I would say he probably doesn’t need the weight of the JVM.

That said, I’m pretty sure I couldn’t do my current project anywhere _but_ the
JVM (well, okay, they’re all Turing machines so technically I can, but bear
with me). I’ll gladly fork over the cash for a beefier VPS if it that’s the
cost of the JVM.

Full disclosure: I am considered a Scala evangelist.

------
dataminer
I fired up an application written in play framework with -Xms64m -Xmx100m and
hit it with ab -n 500 -c 20 <http://localhost:9000/> the RES column in top
remained under 86m. The application does alot more than "hello world", I can
speed it up and decrease memory consumption by substituting groovy based
templates with java based templates using a module called japid. If you want
to use JVM for hobbyist apps start using frameworks which are not based on
j2ee.

------
SkyMarshal
TLDR: JVM uses too much memory for little/hobby projects.

Response: Learn to manually configure its memory useage, don't just go with
the default.

Not really front-page worthy.

~~~
jshen
Can you throw up a hello world project on github and tell me which arguments
to pass it to get the memory lower? I've tried, but maybe I've missed
something.

~~~
saryant
If you’re launching your hello world project in the CLI, you’d just add
-Xmx=64m or whatever size you need. 64 tends to be the default and I haven’t
personally tried pushing it lower (for my work I actually have to push it up
into the 3-6G range. Ah, language processing).

~~~
jshen
Try it, I did. I can't get a servlet to use under 100MB after getting hit with
a moderate amount of traffic. It runs out of heap.

~~~
headius
Use a smaller servlet engine. Most of them assume you will be fine with a
larger heap and prepare caching structures, etc with that in mind Others are
smaller and lighter.

~~~
jshen
Which are good for low memory?

------
spitfire
Further, today bandwidth equals performance. use 100M of memory? suddenly
you've clobbered your cache. Use 10K instead, and it'll fit inside your cache
neatly.

------
mahmud
I'm reading this article while Eclipse restarts after I shutdown the app
because it ran out of PermGen space.

I ran web apps that serviced 10x more users off of a 512 meg VPS with SBCL :-|

Anybody up for a sword-fight? jousting?

~~~
linbsd
Curious as I am learning CL. What did framework did you use with SBCL?

~~~
mahmud
Restas + closure-template is my favorite now.

------
rvijapurapu
Yup, JVM takes up huge resources. But, when you put the app in production, you
can be rest assured it will perform. JVM gives you piece of mind.

~~~
linbsd
Until any given thread consumes too much of the heap and the jvm goes
catatonic. See this all the time with jruby with 6 rails app in a single jvm
instance.

~~~
rvijapurapu
Maybe you should reconsider how you have designed your setup.

Do some testing to see how much memory you have allocated to the JVM - how
much resources each of your rails apps are consuming.. Use a Heap Analyser (or
similar) - it could give you good insights into what is hogging up the
resources.

------
mark_l_watson
I just checked, and a small Clojure web app I am working on does indeed take
almost 100MB of RSIZE - but it have its only JETTY container and a lot of
other overhead that it is not sharing with other deployed apps. Also, a large
app with a lot of code would not take much more. Hosting ten small web apps in
the same Tomcat or Jetty instance would probably take much less than the 1 GB
of RSIZE mentioned in the article.

I do agree though with the goodness of reducing memory use and I like to check
memory use and execution speed when I look at comparative benchmarks like
Computer Language Benchmarks Game.

~~~
jshen
I've run into lots of headaches trying to run multiple apps in the same
container. It's been a while so maybe this has improved over time.

------
kumarm
You want to develop a server app and 100MB required by container is your
concern? BTW This is year 2011 not 1996.

------
sbcoded
I feel like the JVM has already proven its self to be viable as a production
VM. The 'helloworld' argument doesn't really hold water because you would
never run helloworld in a vm. If you care about fast setup/teardowns or small
memory footprints then don't use ANY vm. If you want things like easier
security policies, garbage collection and maybe more the point: scalability
then the VM is a great platform to develop for.

~~~
teyc
The point is that it is too expensive RAM-wise to even serve as a gateway drug
for hobbyists to venture into more serious JVM based projects.

~~~
sbcoded
I feel like when you hobby you run stuff on your local machine. Are you saying
that your local machine doesn't have atleast 1GB of memory? Saying that it
can't run hobby projects is a bit of a stretch.

~~~
teyc
The author is talking about hosting web applications. If you have half a dozen
toyapps, which have an audience ranging from 0-10, you couldn't host them on
separate JVMs on a VPS. There's not enough RAM for this scenario.

~~~
jshen
My audience is more like 5k to 10k per day per app. I just got 2k visitors
from this post.

------
democracy
"hello world" - win xp 32 bit, sun jdk 6:

public static void main(String[] args) throws Exception { Thread.sleep(10000);
System.out.println("hello world"); }

Heap - 5M, Used heap - below 2M. All defaults.

(the "sleep" is there to have time to connect Java VisualVM)

~~~
democracy
Sorry, I missed you are talking about "'hello world' web app", anyway there is
no such thing a 'hello world' web app, there are very different
application/web servers out there and you can't obviously compare jetty vs
built-in jdk 6 com.sun.net.httpserver.HttpServer and WebSphere.

------
chrismealy
Hold on, my rails processes take 80 megs. Am I doing something wrong?

~~~
jshen
On the JVM it will take over 300MB with JRuby. A simple 'hello world' servlet
on the JVM takes over 100MB (once you hit it with a little traffic).

~~~
headius
Untrue. JRuby can run an app in under 200 MB easily, and close to 100 MB if
tuned right.

~~~
jshen
I didn't spend a whole lot of time trying to tune it, but I used a few of the
standard options. Trinidad, kirk, etc. I was using a real world app, not a
hello world, so there were a number of gems and such outside of vanilla rails.

Edit: This ia a real rails app, so it's a bit of a tangent from my post, but
I'm looking at it right now. I spun it up with trinidad, dev mode, and
requested the home page. It used over 600MB. It's an admittedly heavy
homepage, asset wise, but it will run out of heap if I set the max heap any
lower than 500MB.

Edit 2: let me try it with MRI

Edit 3: MRI took about 225MB, about half the memory. In this case JRuby is
clearly better because we run it in threadsafe mode.

------
bunderbunder
If one actually has a true practical reason to be concerned that processes
won't consume less than $1 worth of RAM, I have to wonder why anything
involving a managed environment such as the JVM was ever up for consideration
in the first place.

I'd figure when dealing with that kind of memory constraint the only real
contenders would be things like C, FORTH, or maybe PICAXE BASIC.

------
DanielRibeiro
Great comment:

 _You can allocate as much or as little memory as your application needs. I
run many personal web projects on a JVM sitting on top of a free-tier AWS EC2
micro-instance. I have tomcat6 instances running with <32MB footprint.

Perhaps you need to better understand what you're putting on the JVM and why
it needs what it does_

~~~
jshen
Please throw up a 'hello world' servlet on github and let me know which
arguments to pass it to reduce the memory usage. I've tried, but I may have
missed something, and yes I've tried all the obvious things like setting the
heap size.

I think the commenter you're quoting is confusing the heap size with the total
size. Or I'm missing something and would love for someone to show me what I'm
missing.

~~~
DanielRibeiro
I don't know about tomcat, as its memory footprint can be quite big. But
Jetty's hello world is a 5 lines in Bash, and takes 9 MB:

<http://wiki.eclipse.org/Jetty/Tutorial/Jetty_HelloWorld>

Java ecosystem is too big, and it is common for newcomers to overlook the
juicy parts. The mainstream frameworks and libraries reflect the mainstream
use of java: big apps for medium/big companies.

~~~
jshen
It's taking 57.6MB for me. That's Real Mem in the macs Activity Monitor.

~~~
DanielRibeiro
Well, I am using this on Ubuntu Lucid, with jdk 1.6.0_25-b06

You may wanna try playing with some variables. With the following command
line:

    
    
       java -cp .:servlet-api-2.5.jar:jetty-all-7.0.2.v20100331.jar -client -XX:MaxPermSize=1M -Xmx2M -Xms2M HelloWorld
    
    

I've added _-client -XX:MaxPermSize=1M -Xmx2M -Xms2M_. It took it down to 7Mb
from 9Mb. However, this should not concern you in VPS/Amazon EC2 instances, as
you can always run linux there, and these problems should not come by.

~~~
jshen
This is on my linux VPS (64bit)

$ java -cp .:servlet-api-2.5.jar:jetty-all-7.0.2.v20100331.jar -client
-XX:MaxPermSize=1M -Xmx2M -Xms2M HelloWorld Error occurred during
initialization of VM Too small initial heap for new size specified

I can't get it to run in under 30MB RES according to top. This is after
hitting it with a little traffic, i'm not sure if you hit yours with any
traffic.

~~~
DanielRibeiro
Ah, 64bit JVM. It likes to think it is of itself as enterprise. One thing that
may help is _-XX:+UseCompressedOops_ , and even _-Xmn1M_.

Note that depending on the enverionment it may say it is too small, so you may
have to ramp up a bit some of these stats. I also get it if I set lower than
then ones I gave.

Note that jvm is very tunnable[1,2]. Also note that you can use a 32 bit jdk
in a 64bit machine. It won't get you beyond 2GB vm, but if you are going for
small memory, this is not something that matters (and it should allow you to
get to a very small memory footprint).

Also note that there are other JVMs, like Oracle's JRockit (with extra memory
options[3]), and KVM[4] (designed for small memory footprint[5]).

But hey, that is lower than 32 MB already!

 _Edit_

You can also try some other lesser drastic measures[6,7]. Note that you are
getting in less mainstream use of the JVM, and things can get a little crazy
in this area.

[1]
[http://www.oracle.com/technetwork/java/javase/tech/vmoptions...](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-
jsp-140102.html)

[2] <http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp>

[3]
[http://download.oracle.com/docs/cd/E15289_01/doc.40/e15060/t...](http://download.oracle.com/docs/cd/E15289_01/doc.40/e15060/tune_footprint.htm)

[4] <http://en.wikipedia.org/wiki/K_virtual_machine>

[5] <http://java.sun.com/products/cldc/wp/>

[6] [http://www.coderanch.com/t/202896/Performance/java/Ways-
redu...](http://www.coderanch.com/t/202896/Performance/java/Ways-reduce-
memory-footprint-JVM)

[7] [http://stackoverflow.com/questions/4893192/process-memory-
vs...](http://stackoverflow.com/questions/4893192/process-memory-vs-heap-jvm)

~~~
jshen
thanks for the thoughtful replies!

~~~
DanielRibeiro
No problem!

------
ericmoritz
I guess you should just run a golang HTTP service behind nginx if memory is
your biggest concern.

If that's not good enough go ahead and write the whole thing using C. You can
get one hell of a small "Hello, World!" program using C.

~~~
jshen
I've become a huge fan of golang for this exact reason :)

------
bsiemon
A blanket statement for a fairly specific use case seems irresponsible.

~~~
jshen
What blanket statement did I make? That I don't use the JVM? That doesn't seem
like a blanket statement to me.

------
ronbeltran
But JVM is here to stay.

------
sceptre
Good for you.. Mr. Knuth

