I didn't like garbage collection before i started working. i thought GC made programs slower. However, after getting a job and gaining more experience with coding, i realized how convenient GC actually is. Not every program needs to run at top speed, and GC helps improve productivity by allowing me to focus on more important tasks instead of manually managing memory. Nowadays, I appreciate GC because it simplifies code and improves readability. While i no longer need to release memory manually, it's still important to understand what happens when objects become unused.
There are two main algorithms for dertermining if objects are no longer in use: reference counting and reachability analysis.
this method is similar to smart pointers in C++.
finalize
method to be called. If so, they are placed in the f-queue
. After finalize
is called, if they still have no refernce chain, they are collected. Objects that do not need finalization are also collected.In the method area, which is similar to the text area, constants and classes can be collected. String objects referncing literals are collected when no longer referenced. Classes are collected when three conditions are met: there are no instances of the class, the class loader has been collected, and there are no references to the class(including
java.lang.Class
refereces or reflection).
Then, we separate them into new and old objects. New objects are frequently collected, while old objects are only collected when necessary. GC needs to check for references from old objects to new ones, even when it intends to collect only the new generation. However, since cross-generational references between old and new generations are rare, it's inefficient to scan the entire old generation or record every reference. Instead, it typically checks for references from the old generation to specific memory sets.
Mark-Sweep
Mark objects that should either be collected or survive, then collect the rest. If the heap contains many objects, this approach can be inefficient, and it may lead to significant memory fragmentation.
Mark-Copy
Separate memory into two blocks. Record objects in one block. After collection, copy surviving objects to the other block.
The new generation garbage collection uses this algorithm. For efficiency, memory is divided into one large block and two smaller blocks. During memory allocation, only the large block and one small block are used. After collection, survivors are copied to the other small block. However, if the surviving objects do not fit into the available space, they are directly added to the old generation.
Mark-Compact
Similar to Mark-Sweep, objects are marked for collection. However, after marking, surviving objects are compacted to one side of memory.
The old-generation garbage collection uses this algorithm. The compaction process is expensive, so it isn't done every time. Instead, it is deferred until memory fragmentation becomes severe enough to impact memory allocation.