JVM Spec 僅兩句話:
唯有載入該類別的 ClassLoader 實例 變為 unreachable 時,類別才可能被卸載。啟動類載入器永遠 reachable,系統類別永不卸載。
JLS 12.7 補充:類別卸載屬效能優化,語意不可依賴,對程式碼透明。API 無顯式卸載介面,故:
Reachable = 任何活執行緒可透過引用鏈存取。Finalizer-reachable 僅透過 finalizer 可達。若 ClassLoader 實例長期被快取或廣泛引用,極難達到 unreachable。
| 場景 | 載入器 | 結果 | 說明 |
|---|---|---|---|
| 自訂 ClassLoader | MyURLClassLoader | 可卸載 | 將載入器變數設 null + System.gc(),輸出 [Unloading class MyClass] |
| 系統類載入器 | AppClassLoader | 不可卸載 | 載入器實例長期被引用,GC 後類別仍在 |
| 擴充類載入器 | ExtClassLoader | 不可卸載 | 同理,載入器實例存活 |
結論:僅在簡單脈絡下、自訂 ClassLoader 才可能卸載;實際應用中(特別是快取策略)幾乎不會發生。
預設 loadClass 第二次直接回傳快取的 Class 實例。強制覆寫 loadClass 呼叫 defineClass 會拋 LinkageError: duplicate class definition。
null,加速其 unreachable 以利 GC 回收舊版本類別與 ClassLoader 記憶體。開發時不可假設類別會被卸載;動態更新請採「新 ClassLoader 實例隔離版本」模式,並妥善管理生命週期。