Reputation: 403481
I have a repeatable situation where a JVM is undergoing heavy GC load. When I request the JVM stats using jmap -heap
, I get the info below (this is from Oracle JDK 1.7.0_25 on linux)
Note that while it says that MaxPermSize
is 256m, it also says that PermGen is sitting at 136MB but at 99.9% capacity.
That could explain the GC thrashing, but my question is why isn't the JVM expanding the PermGen to full available 256m? Is there some parameter that can prevent that pool expansion from happening, and stopping the JVM making full use of that 256m?
Note that the Tenured pool is also getting a bit tight, but nowhere near as much as the permgen.
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 5
MaxHeapFreeRatio = 10
MaxHeapSize = 805306368 (768.0MB)
NewSize = 1048576 (1.0MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 8
SurvivorRatio = 8
PermSize = 50331648 (48.0MB)
MaxPermSize = 268435456 (256.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 43909120 (41.875MB)
used = 495240 (0.47229766845703125MB)
free = 43413880 (41.40270233154297MB)
1.1278750291511195% used
Eden Space:
capacity = 39059456 (37.25MB)
used = 495240 (0.47229766845703125MB)
free = 38564216 (36.77770233154297MB)
1.2679132039114933% used
From Space:
capacity = 4849664 (4.625MB)
used = 0 (0.0MB)
free = 4849664 (4.625MB)
0.0% used
To Space:
capacity = 4849664 (4.625MB)
used = 0 (0.0MB)
free = 4849664 (4.625MB)
0.0% used
tenured generation:
capacity = 389492736 (371.44921875MB)
used = 350542912 (334.30377197265625MB)
free = 38949824 (37.14544677734375MB)
89.99985868799361% used
Perm Generation:
capacity = 143392768 (136.75MB)
used = 143338624 (136.6983642578125MB)
free = 54144 (0.0516357421875MB)
99.96224077353747% used
174149 interned Strings occupying 19526656 bytes.
Upvotes: 4
Views: 2289
Reputation: 1016
What is the total system RAM? is it 32 bit or 64 bit jvm? as far as the main question is concerned (as already answered above) - JVM tries to allocate PermGen space (within the defined bounds) but it throws OOM error when system memory is not available.
But I disagree with Alexey Ragozin - If MaxPermGen Size is given lower than needed then JVM will Halt and throw Perm Gen Space error - No matter how much memory is available in host or other sections of heap [Eden / Tenured].
Upvotes: 0
Reputation: 20065
One possible reason would be that your computer has no more available memory, hence the JVM can't allocate more space for PermGen (you need ~ +30% of available memory than the one configured).
Other reason (and I'm more into this one) would be a weird behaviour of Java Ergonomics. It may be possible that your JVM decide that your PermGen "best size" is 136MB but failed in increasing it at some point. Maybe because of memory leaks caused by your PermGen. You can try to use -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
if you use Concurrent Mark and Sweep GC.
Upvotes: 1