Enable verbose garbage collection | Heap fragmentation due to large objects
Heap fragmentation due to pinned and dosed objects
Overview
Heap fragmentation is seen when the JVM fails to allocate an object when there should be sufficient space on the heap to do so. This occurs because the JVM cannot find a large enough contiguous space on the heap to allocate the requested object.
Fragmentation is caused by the interaction between objects on the heap that cannot be moved and the fact that objects need to be allocated into a single contiguous area on the heap.
These unmovable objects fall into two types:
- Pinned objects
Objects that are referenced from a location not within the Java heap, either by variables in JNI native code or by some part of the JVM's internal structure. These fall into two more sub categories:
- Class objects: Referenced from within the native component of the classloaders and the JIT.
- Other pinned objects.
These types of objects tend to be long lived, so once allocated they will stay in that location on the heap.
- Dosed objects
Transiently pinned objects that cannot be moved during the current GC cycle because references to them are held on the stack of a currently executing thread. They are either...
- temporary local variables to the methods in the call stack
- parameters that have been passed between methods within the call stack
To reduce fragmentation caused by pinned and dosed objects, a solution is to group these unmovable objects together into pools. In Java SDK 1.4.2, the GC allocates a kCluster as the first object at the bottom of the heap. A kCluster is an area of storage that is used exclusively for class blocks.
IBM recommendation
IBM recommends setting the kCluster size to be 10% more than the number of classes observed at peak.
To find the number of pinned and dosed objects, add the parameter...
-Dibm.dg.trc.print=st_verify...to the Generic JVM Argument field and you will see the number printed out in the GC log.