第二に、オブジェクトの参照
1.ガベージオブジェクト
Javaは、GCルートがアクセスできないオブジェクトをガベージオブジェクトとして呼び出します
2、GCルーツ
GC Roots [コレクション]の症状は、主に次の4つのカテゴリに分類されます。
- 仮想マシンスタック内の参照
- ローカルメソッドスタック内の参照
- メンバー変数
- 静的定数
3.引用分類
Javaは、オブジェクト参照を4つのカテゴリに分類します。
- 強い引用
- ソフトリファレンス
- 弱い参照
- ファントムリファレンス
4.強力な参照
GCルートがアクセスできるオブジェクトは、強力な参照の関係です。このようなオブジェクトは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メソッドを使用すると、オブジェクトをリサイクルする前に何らかの処理を行うことができます。オブジェクトがファイナライズ段階に入ると、GCでリサイクルできるためです
例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());
例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");
}
}