二、对象的引用
1、垃圾对象
Java把那些GC Roots不能访问到的对象,称之为垃圾对象
2、GC Roots
GC Roots [集合]的表现形式,主要有四类:
- 虚拟机栈中的引用
- 本地方法栈中的引用
- 成员变量
- 静态常量
3、引用的分类
Java把对象的引用分为四类:
- 强引用
- 软引用
- 弱引用
- 虚引用
4、强引用
可以被GC Roots访问到的对象,就是强引用的关系。这种对象不可以被GC回收
5、软引用
这种引用关系的对象,当内存不足时,会被GC回收
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、弱引用
这种引用关系的对象,当GC执行垃圾回收时,就会被回收
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、虚引用
这种引用关系的对象,不可以被直接访问到,一般配合引用队列使用,当GC执行垃圾回收时,对象被放置到引用队列里
另外搭配对象的finalize方法,可以做一些对象被回收前的处理工作。因为当对象进入finalization阶段时,就可以被GC回收
示例一:
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());
示例二:
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");
}
}