JVM中也有併發GC,CMS機制

當初看文檔的時候,瞭解到.net CLR中的Background GC機制,它相似於併發GC,當使得在作GC動做是,可以同時進行內存分配。這種機制顯著的減小的stop the world這種事情,使得GC的干擾最小化。算法

當初認爲.net這招很是優秀,足以鄙視JAVA,前幾天看JVM的書,發現JVM也有相似的機制,可是不叫後臺線程,而是稱做CMS(Concurrent Mark Sweep)。併發

從名字就能夠看出併發標記清除的意思。CMS機制僅針對老年代上的垃圾(.net的後臺GC只在第2代上運行。年輕代上的垃圾由其餘回收算法收集),它運行時,分紅4個步驟:異步

初始標記,併發標記,從新標記和最後異步併發清除,其中初始標記和從新標記仍然會stop the world。從網上扒一張圖,能夠看到ide

clipboard[4]

初始標記其實就是標記root對象,速度很快,而併發標記,就是順着root對象的引用鏈開始順藤摸瓜的作標記,併發的進行標記,能夠看到,此處GC線程和用戶線程是同時運行的。性能

從新標記實際上是對併發標記的一個補充修正,由於有些對象在併發標記後,又被釋放掉或者又被從新引用,致使以前的標記不許確,從新標記一次。從新標記這個動做的速度是很是快的。接着併發清理時,又是和用戶線程同時進行。所以,相比非併發的處理,這種機制有助於減小GC對用戶程序的影響。.net

不過CMS也有缺點,它雖然不會stop the world,可是會佔用CPU資源,會拖慢程序。還有一個缺點CMS收集器沒法處理浮動垃圾,可能出現「Concurrent Mode Failure」失敗(至於爲何會出現這種失敗,書中也沒說的很清楚)。這種失敗致使另外一次Full GC的產生。這招反而會影響性能。最後一個缺點是大多數標記清除算法共有的缺點,就是在回收後,可能會致使大量的碎片空間,當分配大對象的時候,但碎片太多找不到連續的大空間,也會致使一次Full GC。線程

相關文章
相關標籤/搜索