Google I/O 2017上推出的新 GC 演算法的原理是怎樣的?

如題

本題已收錄至知乎圓桌:Google I/O 2017,更多「Google I/O」相關話題歡迎關注討論


看了下youtube上的視頻 https://www.youtube.com/watch?v=iFE2Utbv1Oo

貌似之前的Compact Copying Collector並不是concurrent的,然後在Android O里調整成為了Concurrent Copying Garbage Collector. 新的GC簡單來說就是利用了read barrier來使得應用程序代碼可以在GC過程中耗時最大的那些階段依舊同GC一起運行。圖是從Presentation里粘出來的,侵權刪。

新的GC分為Pause, Copying, Reclaim三個階段,以Region為單位進行GC。

Pause階段:

這個階段耗時非常少,這裡很重要的一塊兒工作是確定需要進行GC的region。當前進程中所有正被使用的那些region中存在高度碎片的region會被選中,而這些被選中的region被稱為source region。在GC完成後這些被選中的source region就可以被釋放了。從圖中可以看出本次GC選中了中間的兩個碎片比率很大的region作為source region。在Pause階段完成對所有線程stack的walk並得到最終的root set之後,就可以喚醒所有的線程並進入到GC的下一個Copying階段。

Copying階段:

Copying階段是整個GC中耗時最長的階段。通過將source region中根據root set計算並標記為reachable的對象拷貝到destination region,並且確保在GC完成後沒有任何指向source region中內存的引用,然後修改所有指向source region的活對象使他們指向新的destination region中的新地址。由於現在應用程序線程正在同GC線程一同運行,GC需要確保其它線程不會讀到依舊指向source region的對象,而新的GC則使用了read barrier技術來達到這個目的。

所謂read barrier是一小段代碼,並且被運行期環境(runtime)安插在field read前來防止其它線程看到指向source region的引用。如果其它線程在Copying階段需要訪問曾經存在於source region中的對象,GC的read barrier邏輯會負責截獲這個讀取並且將數據拷貝到destination region然後返回這個被拷貝到destination region的新引用。當所有的source region的所有reachable對象都被轉移到destination region之後就可以進入到GC的下一個Reclaim階段了

Reclaim階段:在經過Copying階段後,整個進程中就不再存在指向source regions的引用了,GC就可以將這些source region的內存釋放供以後使用了。

新的GC演算法在提高了GC效率的同時還得益於對後台任務甚至系統後台任務的支持,整個heap的平均尺寸得到了32%的下降。

而平均GC Latency也得到了大大的降低,具體對比見圖

另外由於heap總是經過compact的,從而可以實現Thread Local Bump Pointer的簡單內存分配器,因為現在分配內存不再需要複雜的free list管理只需要一個簡單的pointer bump,內存分配的速度也得到了顯著的提升。


推薦閱讀:

學習android開發需要哪些基礎?
安卓應用為什麼要在內部存儲留下這麼多文件?
程序員在公司沒事幹時候,做什麼好?
eclipse中運行安卓模擬器為什麼這麼慢?
20K的Android程序員需要哪些技能?

TAG:Android開發 | GoogleIO | GC垃圾回收計算機科學 | AndroidRuntimeART |