JVM學習之JVM垃圾收集

    垃圾回收歷史,早在Lisp 就有了垃圾收集的功能.垃圾收集的問題主要在三個地方:哪些對象須要回收,在何時回收對象,如何回收對象.
java

一.哪些對象須要回收算法

    判斷哪些對象須要回收的算法主要有兩種,引用計數算法,可達性分析算法.
多線程

        1.引用計數算法:
線程

            一個變量引用一個對象的時候,該對象的引用計數器就加1,有多少個變量引用對象,那這個對象的引用計數器就是多少,少一個引用的時候就減1.直到引用計數器變成0,就成爲可回收對象.
對象


        2.可達性分析算法
內存

            從一個名爲ROOTGC出發遍歷,只要從ROOTGC經過對象內的引用沒法到達的對象就是可回收對象.能夠選擇類變量做爲ROOTGC.
虛擬機

        

          關於Java中的引用,java中分爲強引用,軟引用,弱引用,虛引用.效率

        強引用:就是A a = new A();
變量

        軟引用: 內存回收以前對軟引用的對象進行回收   SoftReference
互聯網

        弱引用:下次垃圾回收必定會執行到. WeakReference

        虛引用:沒法經過虛引用去獲取對象,只能在對象被回收的時候收到系統的一個通知.

二.怎麼回收

       垃圾回收算法:標記清除算法,複製算法,標記整理算法,分代算法

            1.標記清理算法: 標記兩次,第二次標記完成以後就清理,標記效率低下,會產生大量內存碎片.

    

                 如圖所示,紅色是沒被標記內存,灰色是標記內存.,第二次編輯完成以後清除灰色區域,而後會有很   多不連續的內存碎片.

        2.複製算法

            將內存分爲兩塊,對象只放其中一塊上面,在須要回收的時候,把全部對象移動到另外一塊內存上.而後回收以前的那塊內存.有人通過分析,Eden:Survivor Fron:To = 8:1:1是比較合理的狀況.

        3.標記整理算法

                將非標記的對象移動到一塊兒,而後清理全部內存.

        4.分代回收算法

                根據對象存貨週期不通,分紅新生代,老年代,在新生代裏面因爲被回收的概率較大因此使用複製算法,在老年代裏面因爲被回收的概率較小使用標記標記整理算法.這樣的組合使用大大的提升了垃圾回收的效率

在HotSpot中GC的時候須要停頓全部執行中的java線程,以保證可達性分析的準確性.



垃圾收集器

是由java虛擬機實現的垃圾算法的實現.

新生代中的垃圾收集器:

  1. Serial收集器 : 使用複製算法,在進行垃圾回收的時候停頓全部java線程.簡單高效.

  2. ParNew收集器 : 複製算法,是Serial收集器多線程的實現.  默認線程數與CPU個數相同.經過 --XX:ParallelGCThreads設置線程大小.

  3. Parallel Scavenge收集器:  和ParNew收集器差很少,可是關注點是達到可控制的吞吐量(用戶代碼運行時間/(用戶代碼運行時間+GC時間)). 經過--XXMaxGCPauseMills設置最大垃圾回收時間. --XX: MaxGcTimeRate設置吞吐量大小.

老年代中的垃圾收集器:

    1.Serial Old收集器: 使用標記整理算法.是Serial收集器的老年代版本.

    2.Parallet Old收集器:是Parallet Scavenge收集器的老年版本.

    3.CMS收集器(Concurrent Mark Sweep) : 使用標記清楚算法,關注點是最短回收時間.適用於互聯網和B/S系統的服務端


垃圾回收過程:

大多數狀況對象在Eden去進行分配,(比較小的狀況如對象比較大的時候會直接放到老年代中),當Eden區沒有足夠的空間的時候,會進行一次Minor GC(把Eden存活對象和非空的Servivor中存活對象複製到空的Servivor空間,而後清除Eden和以前的Servivor空間).每通過一次Minor GC還存活的對象的年齡加一,當年齡達到必定數(默認15)的時候進入老年代.在發生Minor GC以前會檢查一下老年代空閒空間是否足夠,不夠的話進行一次Full GC.

相關文章
相關標籤/搜索