2011년 11월 7일 월요일

[IBM JVM] Avoiding Java heap fragmentation with Java SDK V1.4.2.

Avoiding Java heap fragmentation with Java SDK V1.4.2.

Problem(Abstract)

What are pinned objects in Java™ and how you can avoid fragmentation?

Resolving the problem

Objects that are on the Java heap are usually mobile; that is, the garbage collector can move them around if it decides to re-sequence the heap. Some objects, however, cannot be moved either permanently, or temporarily. Such immovable objects are known as pinned objects.

In the Java SDK release 1.4.2, the garbage collector 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. It is large enough to hold 1280 entries. Each class block is 256 bytes long.

The garbage collector then allocates a pCluster as the second object on the heap. A pCluster is an area of storage that is used to allocate any pinned objects. It is 16 KB long.

When the kCluster is full, the garbage collector allocates class blocks in the pCluster. When the pCluster is full, the garbage collector allocates a new pCluster of 2 KB. Because this new pCluster can be allocated anywhere, it can cause problems.

To remove these problems, release 1.4.2 uses a pinnedFreeList, which changes the way in which the pCluster is allocated. The concept is that after every garbage collection, the garbage collector takes an amount of storage from the bottom of the free list and chains it from the pinnedFreeList. Allocation requests for pClusters use the pinnedFreeList, while other allocation requests use the free list. When either free list is exhausted, the garbage collector causes an allocation failure and a garbage collection. This action ensures that all pClusters are allocated in the lowest-available storage location in the heap.

The garbage collector uses this algorithm to determine how much storage to put on the pinnedFreeList:
  • The initial allocation is for 50 KB.
  • If this is not the initial allocation and the pinnedFreeList is empty, the garbage collector allocates 50 KB or five times the amount of allocations from the clusters since the last garbage collection, whichever is larger.
  • If this is not the initial allocation and the pinnedFreeList is not empty, the garbage collector allocates 2 KB or five times amount of allocations from the clusters since the last garbage collection, whichever is larger.

This algorithm increases the amount of storage that is available when the application is loading many classes. It therefore avoids an allocation failure that is due to an exhausted pinnedFreeList. It also reduces the amount of storage that is on the pinnedFreeList when only a small allocation of pinned clusters exists, and therefore avoids the need to remove large amounts of storage from the free list.

The buildPinnedFreeList function builds the pinnedFreeList by using the above algorithm. This function is called from the following places:
  • In initializeClusters
  • At the end of expandHeap
  • At the end of gc0_locked

The garbage collector makes allocations from the pinnedFreeList by calling the nextPinnedCluster function. This function works in a way that is similar to the way in which nextTLH works; that is, it always takes the next available free chunk on the pinnedFreeList. If the pinnedFreeList is empty, it calls manageAllocFailure.

In realObjCAlloc, if no room remains in the clusters, the garbage collector calls nextPinnedCluster to allocate a new pCluster.

In initializeClusters, the garbage collector calls nextPinnedCluster, which allocates an initial pCluster of 50 KB because 50 KB is the size of the only free chunk that is on the pinnedFreeList. The free chunk has that size because the pinnedFreeList had the initial allocation of 50 KB.

For a large Java application, such as IBM® WebSphere® Application Server, the default kCluster space might not be sufficient to allocate all classblocks. With Version 1.4.2, you can use the -Xk command-line option to specify kCluster size. For example:

-Xknnnn 

where nnnn specifies the maximum number of classes the kCluster contains. -Xk instructs the JVM to allocate space for nnnn class blocks in kCluster.

GC trace data obtained by setting -Dibm.dg.trc.print=st_verify provides a guide for the optimum value of the nnnn parameter on version 1.4.2.


For example:

<GC(VFY-SUM): pinned=4265(classes=3955/freeclasses=0) dosed=10388 movable=1233792 free=5658>

The pinned and classes sizes are about the right size needed for the -Xk parameter. We recommend that you add 10% to the reported value (3955). In this example, -Xk4200 is a good setting.


If your application suffers from heap fragmentation, use GC trace and specify the -Xk option. If the problem persists, experiment with higher initial pCluster settings and overflow pCluster sizes.

IBM® HeapAnalyzer can provide a recommended kCluster size from Java heap dump analysis.

IBM Pattern Modeling and Analysis Tool for Java Garbage Collector can provide more accurate recommendations on kCluster size from verbose garbage collection trace with -Dibm.dg.trc.print=st_verify enabled.

-Dibm.dg.trc.print=st_verify can be applied to WebSphere Application Server by adding the setting to the Generic JVM arguments on the Java Virtual Machine Settings page or Java Virtual Machine Configuration. Refer to the following document for the navigation to Generic JVM arguments in the Administrative Console:
http://www.ibm.com/support/docview.wss?uid=swg21114927

Related information

댓글 없음:

댓글 쓰기