Java (JRockit JVM) Memory Management
Java objects reside in an area called the heap.
The heap is created when the JVM starts up and may increase or decrease in size while the application runs..
The heap is divided into two generations called the nursery (or young space) and the old space.
During object allocation, the JRockit JVM distinguishes between small and large objects.
The limit for when an object is considered large depends on the JVM version (between 2 and 128 kB).
Small objects are allocated in thread local areas (TLAs).
Large objects are allocated directly in old space
Large objects requires more synchronization between the Java threads, although the JRockit JVM uses a system
of caches of free chunks of different sizes to reduce the need for synchronization and improve the allocation speed.
Garbage Collection is the process of freeing space in the heap or the nursery for allocation of new objects.
- The Mark and Sweep Model
A mark and sweep garbage collection consists of two phases, the mark phase and the sweep phase.
During the mark phase all objects that are reachable from Java threads, native handles and other root sources
are marked as alive, as well as the objects that are reachable from these objects and so forth.
This process identifies and marks all objects that are still used, and the rest can be considered for garbage collection.
In sweep phase the heap is traversed to find the gaps between the live objects and recorded these gaps
in a free list and are made available for new object allocation.
One is mostly concurrent mark and sweep and the other is parallel mark and sweep.
- Concurrent Mark and Sweep - Allows the Java threads to continue running during large portions of the GC.
- Concurrent Mark and Sweep - The threads must however be stopped a few times for synchronization
- The parallel mark and sweep/ parallel garbage collector - uses all available CPUs in the system for performing the garbage collection as fast as possible.
- parallel GC - All Java threads are paused during the process
- Generational Garbage Collection
The young collector used in the JRockit JVM identifies and promotes all live objects in the nursery
that are outside the keep area to the old space. This work is done in parallel using all available CPUs.
The Java threads are paused during the entire young collection.
Dynamic and Static Garbage Collection Modes
- By default this is being used.
- optimizing the application throughput
The following dynamic modes are available:
- throughput - for maximum application throughput (default)
- pausetime - for short and even pausetimes
- deterministic - for very short and deterministic pause times
The major static strategies are:
- singlepar - which is a single-generational parallel garbage collector (same as parallel)
- genpar - which is a two-generational parallel garbage collector
- singlecon - which is a single-generational mostly concurrent garbage collector
- encon - which is a two-generational mostly concurrent garbage collector
Objects that are allocated next to each other will not necessarily become unreachable/die at the same time.
Heap may become fragmented after a garbage collection, so that the free spaces in the heap are many but small,
making allocation of large objects hard OR even impossible.
Free spaces that are smaller than the minimum thread local area (TLA) size can not be used at all,
and the GC discards them as dark matter until a future GC frees enough
space next to them to create a space large enough for a TLA.
To reduce fragmentation, the JRockit JVM compacts a part of the heap at every garbage new/old collection.
Compaction moves objects closer together and further down in the heap, thus creating larger free
areas near the top of the heap. The size and position of the compaction area as well as the compaction
method is selected by advanced heuristics, depending on the garbage collection mode used.
Compaction is performed at the beginning of OR during the sweep phase and while all Java threads are paused.
- External and Internal Compaction
- External compaction - the objects within the compaction area to free
positions outside the compaction area and as far down in the heap as possible.
- Internal compaction - moves the objects within the compaction area as far down in the
compaction area as possible, thus moving them closer together.
- JVM selects a compaction method depending on the current garbage collection mode
and the position of the compaction area.
- External compaction is typically used near the top of the heap, while internal compaction is
used near the bottom where the density of objects is higher.
- Sliding Window Schemes
Each sliding window moves a notch up or down in the heap at each
garbage collection, until it reaches the other end of the heap or meets a sliding window that moves
in the opposite direction, and starts over again. Thus the whole heap is eventually traversed by
compaction over and over again.
- Compaction Area Sizing
In throughput mode the compaction area size is static, while all other modes, including the static mode,
adjust the compaction area size depending on the compaction area position, aiming at keeping the
compaction times equal throughout the run. The compaction time depends on the number of objects moved
and the number of references to these objects. Thus the compaction area will be smaller in parts of the
heap where the object density is high or where the amount of references to the objects within the area is high.
Typically the object density is higher near the bottom of the heap than at the top of the heap,
except at the very top where the latest allocated objects are found. Thus the compaction areas are
usually smaller near the bottom of the heap than in the top half of the heap.