## 枚舉根節點、安全點、安全區域
在根可達性分析算法中,從GC Roots集合中找引用鏈是虛擬機高效實現的第一個例子。
### 問題一:為什么要枚舉根節點?怎么高效實現?

雖然GC Roots的節點主要在全局性的引用(例如常量或者類靜態變量)與執行上下文(例如棧幀中的局部變量表),但是查找起來并發容易的事。
### 問題一解決之道:使用根可達分析算法判斷垃圾,所以需要枚舉根節點。通過在安全點生成并維護OopMap來高效計算GC Roots集合。
為了解決某個時刻GC Roots集合的定位問題,在HotSpot中,有個數據結構(映射表)稱為**OopMap**。一旦類加載動作完成的時候,HotSpot就會把對象內什么偏移量上是什么類型的數據計算出來,記錄到OopMap。在即時編譯過程中,也會在**特定的位置**生成 OopMap,記錄下棧上和寄存器里哪些位置是引用。這樣在垃圾收集器在**枚舉根節點**時,就可以通過掃描OopMap中的對象快速得到當時的GC Roots集合。
(每個安全點都會生成對應的OopMap)
### 問題二:為什么需要安全點?安全點在哪些位置?
進行垃圾回收的過程中,會涉及對象的移動。為了保證對象引用更新的正確性,必須暫停所有的用戶線程(會發生STW)。線程并不是在任意位置都能中斷掛起的,只有在特定的位置才行。
這些特定的位置:
* 方法調用
* 循環跳轉(非 counted 循環,固定循環次數)
* 異常跳轉
稱之為**安全點**(每個安全點都會生成對應的OopMap),垃圾收集時,需要用戶線程到達安全點停下來后才開始執行。
在HotSpot中,采用主動式中斷的思想讓做垃圾收集時讓所有用戶現在都跑到最近安全點停頓下來。
是在安全點和分配對象時設置一個中斷標志,各線程執行時會不停輪詢這個標志,一旦發現為真時就在最近安全點主動掛起。
### 問題三:為什么需要安全區域?
安全點的設計幾乎完美解決如何停頓用戶線程,讓虛擬機進入垃圾回收狀態。可如果用戶線程處于Sleep或者Blocked狀態時,線程是無法響應中斷請求的,虛擬機也不可能等待線程被激活后走到安全點掛起自己,這個時候就需要安全區域來解決了。
**安全區域**是指能夠確定在某一段代碼之中,引用關系不會發生變化,因此這個區域內任意地方開始垃圾回收都是安全的。(安全區域是擴展了的安全點)
- 面試突擊
- 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一些并行算法的熟悉
- 面試總結
- 長亮一面