Second, the reference of the object
1. Garbage object
Java calls those objects that GC Roots cannot access as garbage objects
2、GC Roots
The manifestations of GC Roots [collection] mainly fall into four categories:
- References in the virtual machine stack
- References in the local method stack
- Member variables
- Static constant
3. Citation classification
Java divides object references into four categories:
- Strong citation
- Soft reference
- Weak reference
- Phantom reference
4. Strong references
The objects that can be accessed by GC Roots are the relationship of strong references. Such objects cannot be recycled by GC
5. Soft references
This kind of referenced objects will be recycled by the GC when the memory is insufficient
Object object = new Object();
SoftReference<Object> softReference = new SoftReference<Object>(object);
System.out.println(object);
System.out.println(softReference.get());
object = null;
System.gc(); // GC
System.out.println(softReference.get()); // java.lang.Object@????????【内存够用】
6. Weak references
This kind of reference relationship will be recycled when the GC performs garbage collection
Object object = new Object();
WeakReference<Object> softReference = new WeakReference<Object>(object);
System.out.println(object);
System.out.println(softReference.get());
object = null;
System.gc(); // GC
System.out.println(softReference.get()); // null
7, virtual references
Objects of this kind of reference relationship cannot be directly accessed. They are generally used in conjunction with the reference queue. When the GC performs garbage collection, the objects are placed in the reference queue.
In addition, with the finalize method of the object, you can do some processing before the object is recycled. Because when the object enters the finalization stage, it can be recycled by GC
Example 1:
Object object = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(object, referenceQueue);
System.out.println(object);
System.out.println(phantomReference.get());
System.out.println(referenceQueue.poll());
object = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(referenceQueue.poll()); // java.lang.ref.PhantomReference@????????
System.out.println(phantomReference.get());
Example 2:
public class TestPhantomReference {
public static void main(String[] args) {
MyClass mc = new MyClass();
ReferenceQueue<MyClass> referenceQueue = new ReferenceQueue<MyClass>();
PhantomReference<MyClass> phantomReference = new PhantomReference<MyClass>(mc, referenceQueue);
mc = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(referenceQueue.poll());
System.out.println(phantomReference.get()); // null
}
}
class MyClass {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize");
}
}