Java Memory Monitor Questions

I have an application that generates PDF files with photographs included. The document generation works fine when there are 15 or fewer photos included. However, sometimes there are users that include 25 or 30 pictures and then generate the document repeatedly in a short period of time (10 - 15 minutes). In this case, the app runs out of java heap space and requires a reboot. I have included the JVM Heap Space graph here: I have a few questions: Why is allocated memory lower than max memory? Why does allocated memory take about an hour to recover to previous levels after a app restart? Any recommendations for what we can do to eliminate this problem on the app server side of things? Are there settings we can change? We are discussing application changes we can make like limiting the number of photos per document, limiting how quickly users can regenerate documents, etc. Thanks, Mike
1 answers

Hi Mike,

That's a very good question, and I see that it's not answered in the little part of documentation that the documentation link points to.

This graph shows a few different things from two categories stacked together:

  • Permanent generation and code cache, which are both not really part of the 'heap'
  • The Java Heap, divided in the Eden, Survivor and Tenured parts.

Here's a stackoverflow question that has an answer about the differences between those two parts:

The 'allocated memory' is simply the sum of all memory parts that are in use right now. The 'max memory' is actually the sum of the max jvm heap size and the max allowed permanent generation size. If you're familiar with the startup parameters of the JVM: it's the -Xmx plus the -XX:MaxPermSize. Those are two separate limits, which causes max memory not to be reached in the graph when only one of the two reaches its limit. So yes, the max memory limit, which is actually two different limits added together may be a bit misleading here.

What do you mean by 'memory takes an hour to recover'? You see that directly after the restart, total memory use (including the unused heap) is lower than before. This is because the fact that the permanent gen / code cache is less big. It also seems that after around one hour, some action may be started which causes more java classes to be read into memory (permgen/codecache, green/blue) and besides that, causes the creation of more objects in the java heap, making the tenured part grow.

If the pdf creation is known to require a lot of objects to be resident in memory at the same time, it might indeed be a good idea to get a grasp of how many you can run at the same time, and instead of directly creating them, just inserting jobs/tasks into a queue which is being handled sequentially. Another option is to get more memory for your app. This app seems to be existing for quite some time already and is still on a contract / sizing method that is not used any more. Maybe if you ask to renew the contract and convert it to the current sizing rules, you might get double of the mem instead (since 512MB is now the smallest size app available, and this one has 256MB). (I'm no sales expert, just try it!)