Java 變量分兩類:
對象生命週期**不等於**引用變量作用域:
void method() {
Object obj = new Object(); // obj 在棧上,對象在堆上
List list = new ArrayList();
list.add(obj); // list 持有 obj 引用
} // obj 引用銷毀,但對象被 list 引用,存活
JVM 通過 **GC Roots** 作為起點,向下搜索引用鏈:
**可達 = 存活,不可達 = 垃圾**。標記-清除/標記-整理/複製算法均基於此。
@Deprecated(since="9")
protected void finalize() throws Throwable {
try {
// 釋放非內存資源:文件句柄、網絡連接、數據庫連接
closeResources();
} finally {
super.finalize(); // 調用父類 finalize
}
}
// Java 9+ Cleaner API
public class Resource implements AutoCloseable {
private static final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
private final ResourceHandle handle;
public Resource() {
this.handle = acquireHandle();
this.cleanable = cleaner.register(this, () -> releaseHandle(handle));
}
public void close() { cleanable.clean(); }
}
| 引用類型 | 創建方式 | GC 回收時機 | 典型用途 |
|---|---|---|---|
| 強引用 | Object obj = new Object() | 永不回收(OOM 拋出前) | 常規對象持有 |
| 軟引用 | SoftReference<T> ref = new SoftReference<>(obj) | 內存不足前回收 | 緩存、圖片載入 |
| 弱引用 | WeakReference<T> ref = new WeakReference<>(obj) | 下次 GC 必回收 | WeakHashMap、監聽器 |
| 虛引用 | PhantomReference<T> ref = new PhantomReference<>(obj, queue) | 隨時回收,入隊通知 | 堆外內存釋放、Cleaner |
// 1. 靜態集合持有對象,生命週期 = JVM
static List
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log
關鍵指標:
- Young GC 頻率/耗時
- Full GC 頻率/耗時/觸發原因
- 堆佔用率趨勢
- 存活對象年齡分佈
- 元空間/壓縮類空間變化
AutoCloseable/Cleaner/PhantomReference