21

I'm playing around with writing some simple Spring-based web apps and deploying them to Tomcat. Almost immediately, I run into the need to customize the Tomcat's JVM settings with -XX:MaxPermSize (and -Xmx and -Xms); without this, the server easily runs out of PermGen space.

Why is this such an issue for Java VMs compared to other garbage collected languages? Comparing counts of "tune X memory usage" for X in Java, Ruby, Perl and Python, shows that Java has easily an order of magnitude more hits in Google than the other languages combined.

I'd also be interested in references to technical papers/blog-posts/etc explaining design choices behind JVM GC implementations, across different JVMs or compared to other interpreted language VMs (e.g. comparing Sun or IBM JVM to Parrot). Are there technical reasons why JVM users still have to deal with non-auto-tuning heap/permgen sizes?

Emil Sit
  • 22,894
  • 7
  • 53
  • 75
  • 4
    Are the perl, python, and rails (ruby isn't rails!) tags really necessary? – hobbs Mar 31 '10 at 05:03
  • Fair enough; thanks for cleaning up the tags. – Emil Sit Mar 31 '10 at 13:52
  • Emil, do a Google trends search for Java, Ruby, Perl and Python. The reason that tune java memory is much higher is because "Java" is a much more searched term than the others because Java's usage is much higher than the other. Don't confuse causality with coincidence. http://www.google.com/trends?q=java,+ruby,+python,+perl – uriDium Mar 31 '10 at 14:25
  • @uriDium Google Trends tells you how often someone searches for something. The estimated hits tells you how many resources Google has found. Anyway, even if you normalize using 'tune X memory usage'/'X', java still has more than the other languages. – Emil Sit Mar 31 '10 at 16:09
  • These parameters are auto-tuning and in most cases you shouldn't have to play with them. However in some case you want to be able to control one or more of these parameters and they are available for you to change. Note: just because you have changed a value, don't assume you have improved the situation, you have to test it really is better because often the default is just as good. – Peter Lawrey Apr 10 '10 at 06:54

5 Answers5

7

The title of your question is misleading (not on purpose, I know): PermSize issues (and there are a lot of them, I was one of the first one to diagnose a Tomcat/Sun PermGen issue years ago, when there wasn't any knowledge on the issue yet) are not a Java specifity but a Sun VM specifity.

If you use a VM that doesn't use permanent generation (like, say, an IBM VM if I'm not mistaken) you cannot have permgen issues.

So it's is not a "Java" problem, but a Sun VM implementation problem.

SyntaxT3rr0r
  • 27,745
  • 21
  • 87
  • 120
  • That's interesting, thanks. Leads to some interesting reading (e.g. http://stackoverflow.com/questions/1009042/what-free-jvm-implementation-has-the-best-permgen-handling); I am doing re-deploys via Hudson periodically which apparently eats up this PermGen space. – Emil Sit Mar 31 '10 at 13:58
5

Java gives you a bit more control about memory -- strike one for people wanting to apply that control there, vs Ruby, Perl, and Python, which give you less control on that. Java's typical implementation is also very memory hungry (because it has a more advanced garbage collection approach) wrt the typical implementations of the dynamic languages... but if you look at JRuby or Jython you'll find it's not a language issue (when these different languages use the same underlying VM, memory issues are pretty much equalized). I don't know of a widespread "Perl on JVM" implementation, but if there's one I'm willing to bet it wouldn't be measurably different in terms of footprint from JRuby or Jython!

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • +1 for the data points of JRuby and Jython, which indicate it's not a language thing, but an implementation thing. – Edmund Mar 31 '10 at 06:34
  • Fair enough; it still seems, though, that it should be possible to add control without forcing everyone to deal with figuring out their max/initial heap size, max perm gen, ... do you have any references to good technical papers? – Emil Sit Mar 31 '10 at 14:07
1

Python/Perl/Ruby allocate their memory with malloc() or an optimization thereof. The limit to the heap space is determined by the operating system rather than the VM, so there's no need for options like -Xmxn. Also, the garbage collection is simpler, based mostly on reference counting. So there's a lot less to fine-tune.

Furthermore, dynamic languages tend to be implemented with bytecode interpreters rather than JIT compilers, so they aren't used for performance-critical code anyway.

dan04
  • 87,747
  • 23
  • 163
  • 198
  • 3
    So why can't the limit to heap space to the VM also be determined by the operating system? Why does it have to be fixed at the time the JVM is started? I'm sure this helps the JVM make a few optimizations to its memory model, but that's not what's driving the difference in performance between Java and Python/Perl/Ruby. – mob Mar 31 '10 at 05:48
  • 1
    @mob The Sun JVM has -XX:+AggressiveHeap for that purpose. "Careful with that axe, Eugene" – Joshua Davis Jun 09 '11 at 19:04
0

The essence of @WizardOfOdds and @Alex-Martelli's answers appear to be correct: Java has an advanced set of GC options, and sometimes you need to tune them. However, I'm still not entirely clear on why you might design a JVM with or without a permanent generation. I have found a bunch of useful links about garbage collection in Java, though not necessarily in comparison to other languages with GC. Briefly:

Happy to update this answer with more details if anyone has them.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Emil Sit
  • 22,894
  • 7
  • 53
  • 75
-1

This is because Tomcat is running in the Java Virtual Machine, while other languages are either compiled or interpreted and run against your actual machine. When you set -Xmx and -Xms you are saying that you want to JVM to run like a computer with am amount of ram somewhere in the set range.

I think the reason so many people run in to this is that the default values are relatively low and people end up hitting the default ceiling pretty quickly (instead of waiting until you run out of actual ram as you would with other languages).

aubreyrhodes
  • 777
  • 4
  • 16
  • 1
    Plenty of other languages run on a VM. There's no reason that the VM abstraction has to include a fixed amount of memory. – hobbs Mar 31 '10 at 05:02
  • 3
    So why does the JVM have (need?) a ceiling at all? Why can't it be flexible enough to request more memory from the OS when the need arises? – mob Mar 31 '10 at 05:30
  • Consider a JVM as a formal VM. It needs a ceiling because you might be managing multiple JVMs on a machine, just as you do regular VMs. the JVM /will/ reduce it's total heap. The issue really is that JVMs are still hard to dynamically ergonomate (my new word). – Jé Queue Apr 16 '10 at 22:54
  • @mob "So why does the JVM have (need?) a ceiling at all? Why can't it be flexible enough to request more memory from the OS when the need arises?" The Sun JVM can be easily configured to do just that. It's not the default because you have to be careful that your process doesn't cause the OS to thrash. – Joshua Davis Jun 09 '11 at 19:02