Garbage collection has the following phases:
All live objects are marked in this phase. All reachable objects in the heap are identified, and every other object is treated as garbage. The marking process is also know as tracing. The marking phase creates and uses a mark bit array, whose bits identify reachable objects in the memory.
The sweep phase uses the mark bit array that is created in the mark phase to identify those chunks of heap storage that can be reclaimed for future allocations. These chunks of heap are added to the pool of free space.
The mark and sweep phases can have threads running in parallel or running concurrently. Parallel activities run while application threads are halted, and concurrent activities run without stopping the application threads.
In this phase, the resulting set of objects are compacted to remove the spaces between them. Even if the heap has enough total free space, allocation failures can occur because there is not enough contiguous free space. This state is called fragmentation of the Java heap.
Compaction is a remedy for fragmentation because it moves objects to the beginning of the heap, with no spaces between them, resulting in a contiguous free space for allocations. When an object is moved, the garbage collection changes all the references to that object, which is a complicated and time expensive process that can result in high pause times. By default, compaction is triggered only in certain circumstances, such as not having enough free space to satisfy the allocation request after sweeping.
-Xnocompactgc parameter as a JVM argument prevents compaction and the
-Xcompactgc parameter forces compaction to occur in every global garbage collection
The different garbage collection policies are compared by:
In some garbage collection policies, certain activities can acquire exclusive access on the JVM, and all other application threads can pause (such as compaction). The amount of pause time is determined by the size of the heap and by the amount of the garbage objects in the heap.
The JVM uses the following techniques to reduce pause times:
Concurrent garbage collection
Generational garbage collection
Pause time has a direct effect on response time of the applications because lower pause times imply higher response times.
The throughput is the amount of data that is processed by an application in a specific time window. For example, if an application can handle 10 client requests simultaneously and if each request takes one second to process, this site can have a potential throughput of 10 requests per second.
The response time is the period from entering a system at a defined entry point until exiting the system at a defined exit point. In a WebSphere Application Server environment, this time is usually the time that it takes from when a request is submitted by a web browser until the response is received at the web browser.
The sections that follow list the garbage collection policies and provide a means to compare
the policies. However, to determine the optimum policy for your system, conduct load tests
using different policy options. You can set these policies as a JVM argument using
-Xgcpolicy:policy_name as follows:
The optthruput policy
This policy includes parallel mark and sweep phases. The collector can use multiple threads to run these two phases. By default, the number of threads that are used is limited by the number of CPUs. Compaction occurs if required. As the name implies, this policy favors a higher throughput than the other policies. Therefore, this policy is more suitable for systems that run batch jobs. However, because it does not include concurrent garbage collection phases, the pause times can be longer than the other policies.
The optavgpause policy
This policy uses concurrent garbage collection to reduce pause times. Concurrent garbage collection reduces the pause time by performing some garbage collection activities concurrently with normal program execution. This method minimizes the disruption that is caused by the collection of the heap. This policy limits the effect of increasing the heap size on the length of the garbage collection pause. Therefore, it is most useful for configurations that have large heaps. This policy provides reduced pause times by sacrificing throughput.
The gencon policy
This policy is the default garbage collection policy for WebSphere Application Server V8.5, and it is the short name for concurrent garbage collection and generational garbage collection combined. This policy includes both approaches to minimize pause times. The idea behind generational garbage collection is splitting the Java heap into two areas, nursery and tenured. New objects are created in a nursery area and, if they continue to be reachable for the tenure age (a defined number of garbage collections), they are moved into the tenured area.
This policy dictates a more frequent garbage collection of only the nursery area rather than collecting the whole heap as the other policies do. The local garbage collection of the nursery area is called scavenge. The gencon policy also includes a concurrent mark phase (not a concurrent sweep phase) for the tenured space, which decreases the pause times of a global garbage collection.The gencon policy can provide shorter pause times and more throughput for applications that have many short-lived objects. It is also an efficient policy against heap fragmentation problems because of its generational strategy.
The balanced policy
You can use the balanced policy only on 64-bit platforms that have compressed references enabled. This policy involves splitting the Java heap into equal sized areas called regions. Each region can be collected independently, allowing the collector to focus on the regions that return the largest amount of memory for the least processing effort. Objects are allocated into a set of empty regions that are selected by the collector. This area is known as an eden space.
When the eden space is full, the collector stops the application to perform a partial garbage collection. The collection might also include regions other than the eden space, if the collector determines that these regions are worth collecting. When the collection is complete, the application threads can proceed, allocating from a new eden space, until this area is full. Balanced garbage collection incrementally reduces fragmentation in the heap by compacting part of the heap in every collection. By proactively tackling the fragmentation problem in incremental steps, the balanced policy eliminates the accumulation of work that is sometimes incurred by generational garbage collection, resulting in less pause times.
From time to time, the collector starts a global mark phase to detect if there are any abandoned objects in the heap that are unrecognized by previous partial garbage collections. During these operations, the JVM attempts to use under utilized processor cores to perform some of this work concurrently while the application is running. This behavior reduces any stop-the-world time that the operation might require.