I have a java application which when in idle state before any complex executions, uses 23 MB in Heap and the java.exe process size in TaskManager was around 194 MB. After some complex operations, the size of java.exe grew up to around 500MB and the heap size also grew up. The Heap size is reduced back to 23MB after a few full GC by calling System.gc() method. But the size of java.exe reduced to around 237MB from around 600MB which still have around 43 MB of data in it. Is there a way to reduce this? Or is that due to some behavior?
2 Answers
This is normal, don't worry. JVM acquires memory when it needs to execute some complex logic. When java is done processing the tasks the JVM will still keep that memory as a reserved space and is not released back to the OS. This architecture helps in performance because JMV does not have to request the same memory again from the underlying OS. It will still be within the range you define in -Xmx JVM parameter.
See this IBM link for some interesting details. http://www-01.ibm.com/support/docview.wss?uid=swg21326774
Unfortunately this is one of the grey areas of JVM; you really don't have much of a control on how OS and JVM share memory between each other. Think of JVM as a Virtual OS that requires some memory to run. Both your parent OS and the VM are hungry for resources and want to hang on to the acquired resources the as much memory as possible. Requesting for more memory from OS is a time consuming operation so most of the JVMs do not release the memory back to the OS even when they don't need it anymore.
See this white paper from Oracle for more details on internal JVM memory management. http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf
I would suggest you to read the IBM link first and then you can delve into the weird world of memory explained in the white paper. Both of these links are very informative and interesting.

- 856
- 6
- 8
-
But -Xmx option is to set the Heap size right? For me the used heap is returned back to the OS when i checked it with VisualVM and YourKit Java Profiler. The heap size is not a problem since the process has the same amount of heap size which it had before the process. But the java.exe process in Windows Task Manager uses more than the amount of memory which it was using before. – Santron Manibharathi May 20 '13 at 13:49
-
Most of your understanding is correct; apart from "`used heap is returned back to the OS`". The heap memory is returned to the JVM for other objects, not the underlying OS. That's why in windows the java.exe seems to be using a lot more memory than what you expect. – Raza May 20 '13 at 14:07
-
But when the Heap Size dropeed from 500MB to 23 MB, Java.exe process has reduced from around 600MB to 237 MB, hence i assumed that the remaining heap reduced is returned to the OS. If it is not reduced, even the Heap size has dropped from 500MB, the size of java.exe must be in around 600 MB right. I am sorry i forgot to mention that java.exe was around 600MB before. – Santron Manibharathi May 20 '13 at 14:16
-
This is one of the grey areas of JVM; and you are not the only one confused about that... Unfortunately what I gave you is the correct description of how JVM works. I am going to edit my answer in a minute to include some more details, can't add much in the comments. – Raza May 20 '13 at 15:01
-
Is there any way to release the memory other than the heap memory held by JVM? Like System.gc() for Heap? – Santron Manibharathi May 21 '13 at 11:25
-
The short answer is no. In fact you `cannot force` the release of heap by System.gc(), a call to the System.gc() is nothing more than a request to JVM to run the GC, there is no guarantee that GC will run on your command. The JVM will decide when it wants to run the GC. See the white paper for the details of that. – Raza May 21 '13 at 11:35
OS footprint of java process are composed from
- java heap (it's size in limited by
-Xmx
) - java classes related metadata (or permanent generation in HotSpot JVM)
- non-heap memory accessible via NIO
- stack space for java threads
Some garbage collection algorithms are returning free memory back to OS, other do not.
In HotSpot JVM, serial old space collector (usually enabled by default) are returning memory back to OS (so you can see shrinking of process). Though, other collector such as -XX:+UseParallelOldGC
or -XX:+UseConcMarkSweepGC
will never return unused heap memory to OS.
HotSpot JVM has options to manage / limit all memory areas mentioned above, you can find comprehensive list of JVM options related to memory sizing and GC tuning in my blog.

- 8,081
- 1
- 23
- 23