三色標記原理,我給應聘者問懵了...

摘要:知道三色標記嗎?是紅黃藍三色標記嗎?

本文分享自華爲雲社區《從三色標記說開去》,原文做者:java初中生。java

【1】關於三色標記

前幾天,公司臨時派我去面試一個java實習生,因爲沒有這方面的任何經驗,因而一不當心,我就問超綱了。面試

問過了java基礎,我隨口又問了一句,知道三色標記嗎?算法

他顯然是懵逼了一瞬間,但也僅僅一瞬間,而後振振有詞地反問,是紅黃藍三色標記嗎?數組

這卻是反把我問住了。安全

面試有問題答不出來,這其實能夠理解,不懂就說不懂,不會就說不會,子曾經曰過,知之爲知之。併發

三色標記,正經來講,就只有黑白灰三個顏色。url

但實際上,三色標記,和顏色其實沒有任何關係,只與一次掃描狀態相關spa

  • 黑色節點,表明根節點或者已掃描完的節點,該節點的子節點也被掃描完;
  • 灰色節點,表明已掃描完的節點,該節點的子節點存在未被掃描的狀況;
  • 白色節點,表明未被掃描的節點。

上圖中,A就是黑色節點,B爲灰色,由於B的子節點C未被掃描,C則是白色節點。.net

若是,掃描結束,C依舊是白色,則C被回收。線程

但這裏會存在一個問題,若是在上圖的狀況下,BC的引用斷掉,而AC的引用被創建,以下圖:

則會出現如下狀況:

  • B掃描完,無引用,變黑。
  • C,按道理說,也會變灰,而後變黑。
  • 但A此時已是黑色節點,則不會掃描其引用,因此C不會被掃描,仍是白色。
  • 最後,C會被當垃圾回收。

這顯然是一個誤操做,由於C當前是根可達的,那該問題怎麼辦呢?

經常使用的垃圾回收器,CMS和G1都給出瞭解決方案。

CMS的方法叫作Incremental Update算法。

該算法從結果入手,判斷掃描完結時,是否有白色對象被黑色對象引用,若是被引用,則經過write barrier寫屏障技術,把黑色的對象從新標記爲灰色,而後從新掃描。

G1的方法叫作SATB算法。

該算法從源頭入手,GC開始以前拍攝快照,設定全部存在引用的對象,都是存活的。

GC掃描以後,再次拍攝快照,將新引用的存活對象標記。

而後將快照疊加。

這樣,C顯示的是被A,B兩個對象引用。

但這樣會有一個弊端,若是此時,AC之間的引用沒有被創建,則C原本應該被回收,但此輪卻並無被回收。

【2】跨代引用的問題

跨代引用這個概念被提出來的時候,不少人都有似曾相識的感受。但具體要說,不少人就說不出因此然來了。

其實,java堆說到底就兩個代(年輕代和老年代),持久代在jdk的某個版本後,就被放到本地方法棧了。

跨代引用,即父節點在一個代,而引用對象在另外一個代。

通常來講,父節點都在老年代,引用對象在年輕代。

如上圖,X引用和Y引用都是屬於跨代引用。

跨代引用通常多發生在G1回收器中,由於G1的內存採用分塊的模式,內存區域不穩定

那麼,年輕代回收(young GC)時,是否要根據可達性分析,遍歷全部的老年代關聯,直到根節點呢。

不須要。

只要父節點在老年代,則一概視爲根節點。

在這裏(跨代引用)要引入兩個概念,結果集和卡表。卡表能夠看做一個老年代分區的集合或者數組,以下圖。

結果集,就是一組相似於map的容器,key存放卡表的下標,value存放引用關係

想一想這樣作的好處是什麼?

【3】安全點和安全區域

java工做線程和垃圾回收線程,通常狀況下,是不能同時進行的。

一般老師講到這個問題的時候,會打個比方:吃飯和洗碗擦桌子。

之因此工做線程和垃圾回收線程不能同時進行,是由於人不能一邊吃飯一邊收拾碗筷(觸手怪除外)。

同理,還有一個問題,你也不能把飯吃到一半,把碗拿過去洗。

因此,你必須在吃完飯的時候,洗碗。

吃完飯的這個時間,就是安全點。

通常來講,安全點是某個線程的結束或者中斷的時間,能夠是方法調用,循環跳轉,異常跳轉等。

再回頭說說垃圾回收的全過程。

  • 業務線程執行過程當中,會不斷輪詢一個標誌位,該標誌位處於垃圾回收線程中;
  • 若是須要作垃圾回收,回收線程會將標誌位改掉;
  • 業務線程收到標誌位信息,會走到安全點,而後中止;
  • 垃圾回收線程啓動,回收垃圾。

那麼,安全區域是什麼呢?

一個區域全部的點都是安全點,這一部分就是安全區域。

仍是拿原來那個例子,若是你晚上減肥,不想吃飯,碗什麼的,隨時均可以洗。

【4】如何查看GC日誌

直接上命令:-XX+PrintGCDetails。

該命令能夠在控制檯打印GC日誌。

日誌內容以下:

【5】終:垃圾回收各指標

吞吐量:指在應用程序的生命週期內,應用程序所花費的時間和系統總運行時間的比值。

公式:吞吐量=系統應用時間/系統總運行時間

垃圾回收器負載:和吞吐量正好相反,垃圾回收器負載指垃圾回收器耗時與系統運行總時間的比值。

公式:吞吐量=垃圾回收時間/系統總運行時間

停頓時間(延遲):指垃圾回收器正在運行時,應用程序的暫停時間。

PS:獨佔回收器延遲長,但吞吐量高,併發回收器,延遲少,但吞吐量低。

垃圾回收頻率:指垃圾回收器多長時間會運行一次。

PS:垃圾回收器的頻率應該是越低越好。

反應時間:指當一個對象被稱爲垃圾後多長時間內,它所佔據的內存空間會被釋放。

PS:即垃圾回收的週期

over~~

堆分配:不一樣的垃圾回收器對堆內存的分配方式多是不一樣的。一個良好的垃圾收集器應該有一個合理的堆內存區間劃分。

本文參考資料:https://blog.csdn.net/xingkongjuhao/article/details/101801460

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索