Java Virtual Machine Garbage Collection淺析

      在軟件開發過程當中,Java開發者每每不用關心JVM內存的申請和回收,由於JVM會統一管理對像內存空間的申請和回收。而c/c++開發中,開發者能夠自已去管理內存.這中間有管理好的,有管理很差的。好比一個新手寫的基於C/C++的server上線後,可能由於內存分配問題,常常宕機,而一個基於Java的Server上線後,也會碰到反應慢,打不開,OutOfMemory等狀況。 html

     雖然JVM GC會統一管理對象的回收,但它也不是無所不能的,它須要你們去了解它,幫助它更好地管理咱們server端的內存。 java

     系統在運行的過程當中會不斷產生新的對象,這些新的對象會佔用必定的內存空間。內存空間是有限的,但對象會不斷的產生,因此JVM會按期清理那些被廢棄的對象(經過根搜索算法,GCRoot沒法達到的對象)。這時候就會產生幾個問題: c++

    按期:什麼時間? a.併發,一邊工做,一邊清理 b.暫停全部工做,清理廢棄對象。 算法

    從最先期的JVM垃圾回收機制來看,JVM並無採起a方式,而是採用了b方式。最先期的Serial垃圾回收器的工做方式是"Stop the World". 爲何JVM沒有采用a方式呢?暫不討論。 "Stop the world"就意味着JVM須要停下手中的工做,來整理一下內存空間。這個時候Server就有了一個停頓時間,若是一個Server運行了100s,GC一次用了2s,那麼它的吞吐量能夠當作98%。 服務器

    下面展現了GC所佔時間,系統吞吐量帶來的影響。 併發

   

 

      是否是GC所佔時間越短,系統的吞吐量越高?right! 首先感謝那些默默爲提升JVM GC效率做出傑出貢獻者的大神們! oracle

      回憶一下,常見的垃圾回收算法: spa

      廢棄對象:簡單來說就是沒有被GCRoot直接或間接引用到的對象。  server

      標記清除: 標記廢棄的對象,直接清除。 會形成內存碎片。 htm

      標記整理: 在標記清除算法的基礎上,最後須要整理一下內存空間。消除碎片

      分代複製:把空間分紅幾塊,把有用的對象copy到另外一塊,而後整塊清除原來的那一塊。頻繁對象的複製,耗時。

      只有這些是不夠的,大神們又發現了部分對象在垃圾回收的過程當中,它們的命很硬,每次都是走走過場。

下圖中咱們能夠發現,大部分對象的生命都很短,很早就被廢棄了。



      最後大神們爲每一個對象加上一個年齡,每經歷一次GC年齡就加1.超過必定的年齡的對象羣衆不須要頻繁的去作GC.  這個時候就發現了兩個羣體。一個羣體是生命比較短暫,另外一個羣體生命比較長。即年青代和老年代。

      年青代每次GC存活的對象比較少,分代複製算法比較適合它們。由於它們須要複製不多。 老年代每次GC存活的對象比較多,比較適合標記整理算法。因此這個時候存在不一樣年代的垃圾收集器。但凡事無絕對的,還須要具體狀況具體分析。  

    

        同時隨着硬件的提升,大部分服務器已是多CPU,這個時候就能夠考慮使用基於並行的垃圾收集器。


Reference:

http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

相關文章
相關標籤/搜索