Java 在 JVM 內建自動記憶體管理機制——垃圾回收器 (Garbage Collector)。它會不定期啟動,掃描堆積區,找出不再被任何引用指向的物件,並釋放其佔用的記憶體。這是 Java 與 C/C++ 等需手動管理記憶體語言最大的差異之一。
Runtime 實例,可查詢總/剩餘記憶體、手動觸發 gc()(僅建議,不保證立即執行)。public class GCTest {
public static void main(String[] argv) {
Runtime rt = Runtime.getRuntime();
System.out.println("Program start");
System.out.println("Free/Total memory (bytes): " + rt.freeMemory() + "/" + rt.totalMemory());
MyObject obj1 = new MyObject(1);
MyObject obj2 = new MyObject(2);
MyObject obj3 = new MyObject(3);
System.out.println("After created three MyObject objects");
System.out.println("Free/Total memory (bytes): " + rt.freeMemory() + "/" + rt.totalMemory());
obj1 = null;
obj2 = null;
obj3 = null; // 解除引用,變為不可達
System.out.println("After released three MyObject objects");
System.out.println("Free/Total memory (bytes): " + rt.freeMemory() + "/" + rt.totalMemory());
// 建議 JVM 執行 GC(不保證立即執行)
System.gc();
System.out.println("After System.gc() suggestion");
System.out.println("Free/Total memory (bytes): " + rt.freeMemory() + "/" + rt.totalMemory());
}
}
class MyObject {
private int id;
private byte[] data = new byte[1024 * 100]; // 佔用約 100KB
public MyObject(int id) { this.id = id; }
}
freeMemory 下降。null 後,物件變為不可達,但 freeMemory 不會立即回升(GC 尚未跑)。System.gc() 後,若 GC 執行,freeMemory 會上升。| 演算法 | 特點 |
|---|---|
| 標記-清除 | 標記存活物件,清除其餘;產生記憶體碎片。 |
| 複製 | 將存活物件複製到另一區域;無碎片,但浪費一半空間。 |
| 標記-整理 | 標記後將存活物件向一端移動;無碎片,效率略低。 |
| 分代收集 | 新生代用複製,老年代用標記-整理;現代 JVM 主流策略。 |
finalize() 做複雜邏輯(不可預測、影響效能)。WeakReference)、軟引用 (SoftReference) 實現快取。-Xlog:gc*) 分析效能瓶頸。GC 讓 Java 開發者免於手動記憶體管理之苦,但理解其運作原理(分代、觸發條件、調優參數)對編寫高效能、低延遲系統至關重要。