Garbage Collection
In Java, the objects of GC are heap space and permanent area
reference counting
For an object A, as long as any object references A, the reference counter of A is incremented by 1, and when the reference is invalid, the reference counter is decremented by 1. As long as the value of object A's reference counter is 0, object A can no longer be used.
Problems with reference counting
Referencing and dereferencing are accompanied by addition and subtraction, affecting performance.
It is difficult to deal with circular references
mark clear
The mark-sweep algorithm is the ideological basis of modern garbage collection algorithms. The mark-sweep algorithm divides garbage collection into two phases: the mark phase and the sweep phase. A possible implementation is to mark all reachable objects starting from the root node first through the root node in the marking phase. Therefore, unmarked objects are unreferenced garbage objects. Then, in the cleanup phase, all unmarked objects are cleaned up.
tag compression
The mark-compression algorithm is suitable for occasions where there are many surviving objects, such as the old age. It does some optimizations based on the mark-sweep algorithm. Like the mark-sweep algorithm, the mark-compress algorithm also needs to start from the root node and mark all reachable objects once. But then, instead of simply cleaning up untagged objects, it compacts all live objects into one end of memory. After that, clear all the space outside the boundary.
replication algorithm
The replication algorithm is not suitable for occasions with many surviving objects, such as the old age.
Compared with the mark-and-sweep algorithm, the copy algorithm is a relatively efficient recovery method.
It divides the original memory space into two pieces, and only uses one piece at a time. During garbage collection, the surviving objects in the memory that are being used are collected. Copy to unused memory block, after that, clear all objects in the memory block in use, swap the roles of the two memory, and complete the garbage collection
The biggest problem with the replication algorithm is: space waste Integrate mark-cleaning ideas
-XX:+PrintGCDetails的输出
Heap
def new generation total 13824K, used 11223K [0x27e80000, 0x28d80000, 0x28d80000)
eden space 12288K, 91% used [0x27e80000, 0x28975f20, 0x28a80000)
from space 1536K, 0% used [0x28a80000, 0x28a80000, 0x28c00000)
to space 1536K, 0% used [0x28c00000, 0x28c00000, 0x28d80000)
tenured generation total 5120K, used 0K [0x28d80000, 0x29280000, 0x34680000)
the space 5120K, 0% used [0x28d80000, 0x28d80000, 0x28d80200, 0x29280000)
compacting perm gen total 12288K, used 142K [0x34680000, 0x35280000, 0x38680000)
the space 12288K, 1% used [0x34680000, 0x346a3a90, 0x346a3c00, 0x35280000)
ro space 10240K, 44% used [0x38680000, 0x38af73f0, 0x38af7400, 0x39080000)
rw space 12288K, 52% used [0x39080000, 0x396cdd28, 0x396cde00, 0x39c80000)
Generational thinking
According to the life cycle of the objects, the short-lived objects are classified as the new generation, and the long-lived objects are classified as the old generation.
According to the characteristics of different generations, select a suitable collection algorithm for
a small number of objects to survive, for a copy algorithm for
a large number of objects to survive, for mark cleaning or mark compression
accessibility
Reachable This object is reachable
from the root node Resurvivable Once all references are released, it is in the revivable state because the object may be resurrected in finalize() Unreachable After finalize(), it may enter the unreachable state Unreachable The touched object cannot be resurrected and the finalize() method test class can be recycled :
public class CanReliveObj {
public static CanReliveObj obj;
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("CanReliveObj finalize called");
obj=this;
}
@Override
public String toString(){
return "I am CanReliveObj";
}
public static void main(String[] args) throws InterruptedException{
obj=new CanReliveObj();
obj=null; //可复活
System.gc();
Thread.sleep(1000);
if(obj==null){
System.out.println("obj 是 null");
}else{
System.out.println("obj 可用");
}
System.out.println("第二次gc");
obj=null; //不可复活
System.gc();
Thread.sleep(1000);
if(obj==null){
System.out.println("obj 是 null");
}else{
System.out.println("obj 可用");
}
}
}
# 输出:
CanReliveObj finalize called
obj 可用
第二次gc
obj 是 null
About the finalize() method, some experience:
avoid using finalize(), careless operation may lead to errors.
Low priority, when it will be called, not sure
when GC will occur, after the object is created, the object that has not called the finalize() method will be placed in a queue with a very low priority.
If it is a method that needs to release resources, you can use try-catch-finally to replace it
Objects referenced in the root
stack Objects referenced by
static members or constants in the method area (global objects)
Reference objects in the JNI method stack
Stop-The-World
A phenomenon of
global pause in Java Global pause, all Java code stops, native code can be executed, but cannot interact with JVM Most of the Dump thread deadlocks are
caused by GC . Check heap dump