二、對象的引用
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");
}
}