JVM系列二:GC策略&內存申請、對象衰老

JVM裏的GC(Garbage Collection)的算法有不少種,如標記清除收集器,壓縮收集器,分代收集器等等,詳見HotSpot VM GC 的種類html

       如今比較經常使用的是分代收集(generational collection,也是SUN VM使用的,J2SE1.2以後引入),即將內存分爲幾個區域,將不一樣生命週期的對象放在不一樣區域裏:young generationtenured generation和permanet generation。絕大部分的objec被分配在young generation(生命週期短),而且大部分的object在這裏die。當young generation滿了以後,將引起minor collection(YGC)。在minor collection後存活的object會被移動到tenured generation(生命週期比較長)。最後,tenured generation滿以後觸發major collection。major collection(Full gc)會觸發整個heap的回收,包括回收young generation。permanet generation區域比較穩定,主要存放classloader信息。java

       young generation有eden、2個survivor 區域組成。其中一個survivor區域一直是空的,是eden區域和另外一個survivor區域在下一次copy collection後活着的objecy的目的地。object在survivo區域被複制直到轉移到tenured區。算法

       咱們要儘可能減小 Full gc 的次數(tenured generation 通常比較大,收集的時間較長,頻繁的Full gc會致使應用的性能收到嚴重的影響)。多線程

堆內存GC
       JVM(採用分代回收的策略),用較高的頻率對年輕的對象(young generation)進行YGC,而對老對象(tenured generation)較少(tenured generation 滿了後才進行)進行Full GC。這樣就不須要每次GC都將內存中全部對象都檢查一遍。性能

非堆內存不GCspa

      GC不會在主程序運行期對PermGen Space進行清理,因此若是你的應用中有不少CLASS(特別是動態生成類,固然permgen space存放的內容不只限於類)的話,就極可能出現PermGen Space錯誤。線程

內存申請、對象衰老過程
1、內存申請過程orm

  1. JVM會試圖爲相關Java對象在Eden中初始化一塊內存區域;htm

  2. 當Eden空間足夠時,內存申請結束。不然到下一步;對象

  3. JVM試圖釋放在Eden中全部不活躍的對象(minor collection),釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區;

  4. Survivor區被用來做爲Eden及old的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,不然會被保留在Survivor區;

  5. 當old區空間不夠時,JVM會在old區進行major collection;

  6. 徹底垃圾收集後,若Survivor及old區仍然沒法存放從Eden複製過來的部分對象,致使JVM沒法在Eden區爲新對象建立內存區域,則出現"Out of memory錯誤";

2、對象衰老過程

  1. 新建立的對象的內存都分配自eden。Minor collection的過程就是將eden和在用survivor space中的活對象copy到空閒survivor space中。對象在young generation裏經歷了必定次數(能夠經過參數配置)的minor collection後,就會被移到old generation中,稱爲tenuring。

  2. GC觸發條件

    GC類型 觸發條件 觸發時發生了什麼 注意 查看方式
    YGC eden空間不足

    清空Eden+from survivor中全部no ref的對象佔用的內存
    將eden+from sur中全部存活的對象copy到to sur中
    一些對象將晉升到old中:
        to sur放不下的
        存活次數超過turning threshold中的
    從新計算tenuring threshold(serial parallel GC會觸發此項)

    從新調整Eden 和from的大小(parallel GC會觸發此項)

    全過程暫停應用
    是否爲多線程處理由具體的GC決定
    jstat –gcutil 
    gc log
    FGC

    old空間不足
    perm空間不足
    顯示調用System.GC, RMI等的定時觸發
    YGC時的悲觀策略
    dump live的內存信息時(jmap –dump:live)

    清空heap中no ref的對象
    permgen中已經被卸載的classloader中加載的class信息

    如配置了CollectGenOFirst,則先觸發YGC(針對serial GC)
    如配置了ScavengeBeforeFullGC,則先觸發YGC(針對serial GC)

    全過程暫停應用
    是否爲多線程處理由具體的GC決定

    是否壓縮須要看配置的具體GC
    jstat –gcutil 
    gc log

    permanent generation空間不足會引起Full GC,仍然不夠會引起PermGen Space錯誤。

參考:

http://jiangyongyuan.javaeye.com/blog/356502

http://www.helloying.com/blog/archives/164

相關文章
相關標籤/搜索