When we create any object using new keyword, some amount of memory will be allocated. Once we done with that object, it should be removed from the memory. Java implements automatic memory management also known as Garbage collection. It will automatically recycle the dynamically allocated memory. Garbage collector will recycle the memory.
Garbage collection was first invented by John McCarthy in 1958 as part of the implementation of Lisp..
Garbage collection organizes objects into generations (Young, Tenured and Perm)..
The young generation consists of eden plus two survivor spaces .Objects are initially allocated in eden. One survivor space is empty at any time, and serves as a destination of the next, copying collection of any live objects in eden and the other survivor space. Objects are copied between survivor spaces in this way until they are old enough to be tenured, or copied to the tenured generation.
The permanent generation is special because it holds data needed by the virtual machine to describe objects that do not have an equivalence at the Java language level .For example objects describing classes and methods are stored in the permanent generation.
The garbage collection can be of 2 types namely:
When the young generation fills up it causes a minor collection. Minor collections can be optimized assuming a high infant mortality rate.
A young generation full of dead objects is collected very quickly. Some surviving objects are moved to a tenured generation. When the tenured generation needs to be collected there is a major collection that is often much slower because it involves all live objects.
*Throughput: Percentage of time not spent in GC over a long period of time.
*Pauses: Application unresponsive during GC
*FootPrint : working set of a process, measured in pages and cache lines.
*Promptness: time between when an object becomes dead and when the memory becomes available
Where we can apply or consider about these above terms?
Lets take an example .Consider the metric for web server application to be Throughput, since Pauses during GC may be tolerable, or simple obscured by network latencies. However, if its an gaming application or interactive graphics application even short Pauses may affect the user experience..
A very large young generation may maximize the Throughput, but remaining 3 will be at expense.. If Young generation is small, then Pauses will be minimized but at the expense of Throughput. We can determine the necessary generation based on the user requirement and the application the way it uses the memory..
How do we measure?
Throughput of web server – can be tested using load generator
Footprint – in Solaris pmap command
Pauses – diagnostic output of virtual machine..
Sizing the Generations
-Xmxvalue determines the size of the heap to reserve at JVM initialization.
-Xmsvalue is the space in memory that is committed to the VM at init. The JVM can grow to the size of
- Total available memory is the most important factor affecting GC performance
- · By default the JVM grows or shrinks the heap at each GC to keep the ratio of free space to live objects at each collection within a specified range.
-XX:MinHeapFreeRatio– when the percentage of free space in a generation falls below this value the generation will be expanded to meet this percentage. Default is 40
-XX:MaxHeapFreeRatio– when the percentage of free space in a generation exceeded this value the generation will shrink to meet this value. Default is 70
Young Generation Guarantee
-XX:SurvivorRatiooption can be used to tune the number of survivor spaces.
- Not often important for performance
-XX:SurvivorRatio=6– each survivor space will be 1/8 the young generation
- If survivor spaces are too small copying collection overflows directly into the tenured generation.
- Survivor spaces too large uselessly empty
-XX:+PrintTenuringDistribution– shows the threshold chosen by JVM to keep survivors half full, and the ages of objects in the new generation.
- Server Applications
- First decide the total amount of memory you can afford to give the virtual machine. Then graph your own performance metric against young generation sizes to find the best setting.
- Unless you find problems with excessive major collection or pause times, grant plenty of memory to the young generation.
- Increasing the young generation becomes counterproductive at half the total heap or less (whenever the young generation guarantee cannot be met).
- Be sure to increase the young generation as you increase the number of processors, since allocation can be parallelized.
Types of Collectors
- Everything to this point talks about the default garbage collector, there are other GC’s you can use
- Throughput Collector – Uses a parallel version of the young generation collector
- Tenured collector is the same as in default
- Concurrent Low Pause Collector
- Collects tenured collection concurrently with the execution of the app.
- The app is paused for short periods during collection
- To enable a parallel young generation GC with the concurrent GC add
-XX:+UseParNewGCto the startup. Don’t add
-XX:+UseParallelGCwith this option.
Recommend to study this :
Java HotSpot VM Options
Examples with explanation:
Netbeans Profiler with screenshot: