In this post, I will delv into more specific details and examples of GC in the JVM. First, I'll explain the main concepts of GC and then examine how various garbage collectors operate.
This process involves earching for reference chains starting from the GC root set.
An OopMap stores information about references in the object's stack and registers once loading is complete. It includes details about which instructions modify references or OopMap data. Creating an OopMap for every instruction would be highly inefficent. Instead, OopMaps are only created for safe points, which are specific points in the code where the program may run for an extended time, such as during method calls, loops, or exception handling.
There are two methods for reaching safe points:
A polling mechanism can use a single assembly instruction. For example, preventing memory access triggers a memory protection trap, which throws an exception handled by an exception handler to temporarily suspend the thead.
A safe region is a state or area where:
The goal of these techniques is to reduce the scope of root scans, which can be expensive when scanning references across generations.
Instead of scanning all references between generations, memory sets record only cross-generational references, allowing the GC to efficiently identify live objects.
A common appraoch to optimize this process is by reducing precision mapping records to memory blocks rather than individual objects.
If an object in another generation references a block in a differenct generation, the refernce is marked in the card table either before or after the reference occurs. While this increases the cost of updating references, it is still lower than scanning the entire generation.
False sharing can occur when physically different varibales are stored in the same cache line. Since the card table manages regions of 512 bytes(the size of card), false sharing can have a significant impact within the range of cache line size multiplied by the card size.
The Garbage Collector can search the object graph after root node enumeration.
It is more critical to mistakenly consider a live object as dead than to consider a dead object as live. This situation can occur when a user thread adds a reference form a black object to a white object and simultaneously removes a reference form a gray object to a white object. Preventing just one of these two scenarios is sufficient to avoid this critical problem.
Incremental Update
Snapshot at the Beginning