## 哪些區域需要垃圾收集
在[熟悉Java內存區域](001%E7%86%9F%E6%82%89Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F.md)文中,知道了JVM運行時數據區有堆、方法區、虛擬機棧、本地方法棧和程序計數器5個部分,后3個部分都是線程私有的,其中的數據會跟隨線程死亡自動回收,所以不需要垃圾收集。而堆和方法區是線程共享的,故垃圾收集主要關注這2個部分。
學習了[垃圾判定算法與4大引用](004%E5%9E%83%E5%9C%BE%E5%88%A4%E5%AE%9A%E7%AE%97%E6%B3%95%E4%B8%8E4%E5%A4%A7%E5%BC%95%E7%94%A8.md)后,我們知道了如何判斷對象是垃圾了。
接下來,我們就開始回收堆和方法區中的無效數據。
## 回收堆
對于可達性分析中不可達的對象,也并不是沒有存活的可能。
### 判定 finalize() 是否有必要執行
JVM 會判斷此對象是否有必要執行 `finalize() `方法,如果對象沒有覆蓋 `finalize() `方法,或者 `finalize()` 方法已經被虛擬機調用過,那么視為“沒有必要執行”。那么對象基本上就真的被回收了。
如果對象被判定為有必要執行 `finalize()` 方法,那么對象會被放入一個 `F-Queue` 隊列中,虛擬機會以較低的優先級執行這些 `finalize()`方法,但不會確保所有的 `finalize()` 方法都會執行結束。如果 `finalize()` 方法出現耗時操作,虛擬機就直接停止指向該方法,將對象清除。
### 對象重生或死亡
如果在執行 `finalize()` 方法時,將 this 賦給了某一個引用,那么該對象就重生了。如果沒有,那么就會被垃圾收集器清除。
**任何一個對象的 finalize() 方法只會被系統自動調用一次,如果對象面臨下一次回收,它的 finalize() 方法不會被再次執行,想繼續在 finalize() 中自救就失效了。**
## 回收方法區
方法區存放生命周期較長的已加載的類信息、常量、靜態變量和即時編譯器編譯后的代碼4個部分,主要回收:
* 無用的類
* 廢棄常量
### 判定無用的類
判定一個類是無用的,條件比較苛刻:
* 該類的所有對象都已被清除。
* 加載該類的`ClassLoader`被回收。
* 該類的`java.lang.Class`對象沒有被任何地方引用,無法在任何地方通過反射訪問該類的方法。
滿足上面3個條件的類,虛擬機會進行回收。(通過`-Xnoclassgc`參數控制)
一個類被虛擬機加載進方法區,那么在堆中就會有一個代表該類的對象:`java.lang.Class`。這個對象在類被加載進方法區時創建,在方法區該類被卸載時清除。
在大量使用反射、動態代理、CGLib等字節碼框架、動態生成JSP以及OSGI這類頻繁自定義ClassLoader的場景都需要虛擬機具備類卸載的功能,以保證方法區不會溢出。
### 判定廢棄常量
條件:只要常量池中的常量不被任何變量或對象引用,那么這些常量就會被清除掉。
比如,一個字符串 "abc" 進入了常量池,但是當前系統沒有任何一個 String 對象引用常量池中的 "abc" 常量,也沒有其它地方引用這個字面量,必要的話,"abc"常量會被清理出常量池。
## 參考資料
* 周志明 * 《深入理解Java虛擬機》
- 面試突擊
- Java虛擬機
- 認識字節碼
- 000Java發展歷史
- 000Macos10.15.7上編譯OpenJDK8u
- 001熟悉Java內存區域
- 002熟悉HotSpot中的對象
- 003Java如何計算對象大小
- 004垃圾判定算法與4大引用
- 005回收堆和方法區中對象
- 006垃圾收集算法
- 007HotSpot虛擬機垃圾算法實現篇1
- 007HotSpot虛擬機垃圾算法實現篇2
- 007HotSpot虛擬機垃圾算法實現篇3
- 008垃圾收集器
- 009內存分配與回收策略
- 010Java虛擬機相關工具
- 011調優案例分析
- 012一次IDEA的啟動速度調優
- 013類文件Class的結構
- 014熟悉字節碼指令
- 015類加載機制(過程)
- 016類加載器
- IDEA的JVM參數
- Java基礎
- Java自動裝箱與拆箱
- Java基礎數據類型
- Java方法的參數傳遞
- Java并發
- 001走入并行的世界
- 002并行程序基礎
- 003熟悉Java內存模型JMM
- 004Java并發之volatile關鍵字
- 005線程池入門到精通
- 006Java多線程間的同步控制方法
- 007Java維基準測試框架JMH
- 008Java并發容器
- 009Java的線程實現
- 010Java關鍵字synchronized
- 011一些并行模式的熟悉
- 單例模式和不變模式
- 生產者消費者模式
- Future模式
- 012一些并行算法的熟悉
- 面試總結
- 長亮一面