爲什麼CMS兩次標記時要 stop the world(阿里面試)

1、CMS及其執行過程?

       CMS,全稱Concurrent Mark and Sweep,用於對年老代進行回收,目標是儘量減少應用的暫停時間,減少full gc發生的機率,利用和應用程序線程併發的垃圾回收線程來標記清除年老代。CMS並非沒有暫停,而是用兩次短暫停來替代串行標記整理算法的長暫停。

       內外的設置正常收集週期是這樣的

       1)CMS-initial-mark 初始標記
  2)CMS-concurrent-mark 併發標記的
  3)CMS-concurrent-preclean 執行預清理   注: 相當於兩次 concurrent-mark. 因爲上一次c mark,太長.會有很多 changed object 出現.先幹掉這波.到最好的 stop the world 的 remark 階段,changed object 會少很多.
  4)CMS-concurrent-abortable-preclean 執行可中止預清理  
  5)CMS-remark 重新標記
  6)CMS-concurrent-sweep 併發清除
  7)CMS-concurrent-reset 併發重設狀態等待下次CMS的觸發

其中,CMS-initial-mark和CMS-remark會stop-the-world。

2、爲什麼 CMS兩次標記時要 stop the world?

       我們知道垃圾回收首先是要經過標記的。對象被標記後就會根據不同的區域採用不同的收集方法。看上去很完美的一件事情,其實並不然。 
  大家有沒有想過一件事情,當虛擬機完成兩次標記後,便確認了可以回收的對象。但是,垃圾回收並不會阻塞我們程序的線程,他是與當前程序併發執行的。所以問題就出在這裏,當GC線程標記好了一個對象的時候,此時我們程序的線程又將該對象重新加入了“關係網”中,當執行二次標記的時候,該對象也沒有重寫finalize()方法,因此回收的時候就會回收這個不該回收的對象。 
  虛擬機的解決方法就是在一些特定指令位置設置一些“安全點”,當程序運行到這些“安全點”的時候就會暫停所有當前運行的線程(Stop The World 所以叫STW),暫停後再找到“GC Roots”進行關係的組建,進而執行標記和清除。 
  這些特定的指令位置主要在:

  • 1、循環的末尾
  • 2、方法臨返回前 / 調用方法的call指令後
  • 3、可能拋異常的位置

 感謝兩位大佬的總結:https://blog.csdn.net/fei33423/article/details/70941939

https://blog.csdn.net/wwwtotoro/article/details/72763043

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章