The reduction in size could be due to, when dumping its heap, the JVM will first run a garbage collection cycle to free any unreachable objects.
If you want to get deeper on how the memory is being used, you should start by checking how the Garbage Collector is doing.
First, the flags you are using don't handle the heap size
-XX:PermSize -XX:MaxPermSize
are used to set size for Permanent Generation. Permanent Generation: The Permanent Generation is where class files are kept. But think of this as the class metadata, not the actual objects, those go to the heap (with some caveats)
Then set your preferences correctly for your JVM with the flags-Xms1024m -Xmx1024m
and enable more logging -verbose:gc -XX:+PrintGCDetails
.
You will get something like this:
Heap
def new generation total 314560K, used 100261K [0x00000000c0000000, 0x00000000d5550000, 0x00000000d5550000)
eden space 279616K, 35% used [0x00000000c0000000, 0x00000000c61e9370, 0x00000000d1110000)
from space 34944K, 0% used [0x00000000d3330000, 0x00000000d3330188, 0x00000000d5550000)
to space 34944K, 0% used [0x00000000d1110000, 0x00000000d1110000, 0x00000000d3330000)
tenured generation total 699072K, used 368281K [0x00000000d5550000, 0x0000000100000000, 0x0000000100000000)
the space 699072K, 52% used [0x00000000d5550000, 0x00000000ebcf65e0, 0x00000000ebcf6600, 0x0000000100000000)
And check the life of your objects, see how they "age" on every GC collection.
These definitions below will help you to understand the lifecycle of objects in the heap better if you already don't
Heap memory
The heap memory is the runtime data area from which the Java VM allocates memory for all class instances and arrays. The heap may be of a fixed or variable size. The garbage collector is an automatic memory management system that reclaims heap memory for objects,
Eden Space: The pool from which memory is initially allocated for most objects.
Survivor Space: The pool containing objects that have survived the garbage collection of the Eden space.
Tenured Generation or Old Gen: The pool containing objects that have existed for some time in the survivor space.
So if you end up with OldGen you, that would trigger a Full GC, and that may indicate you have a memory leak.
This may also cause java.lang.OutOfMemoryError: GC overhead limit exceeded
errors
In this case, I'd inspect further the objects there to find the worm.
Otherwise, it could be that you have a high churn of short lived objects, this happens usually in ETL applications. Try to check your code to avoid instantiating objects as much as possible (check the Flyweight pattern)
And if none of these happens you could say your JVM is healthy.
top
orfree
, so you're assuming things. You need to profile your application to see the real memory usage and what's making things slow.