您好,登錄后才能下訂單哦!
JVM里的GC(GarbageCollection)的算法有很多種,如標記清除收集器,壓縮收集器,分代收集器等等,詳見HotSpotVMGC的種類
現在比較常用的是分代收集,即將內存分為幾個區域,將不同生命周期的對象放在不同區域里:younggeneration,tenuredgeneration和permanetgeneration。絕大部分的objec被分配在younggeneration(生命周期短),并且大部分的object在這里die。當younggeneration滿了之后,將引發minorcollection(YGC)。在minorcollection后存活的object會被移動到tenuredgeneration(生命周期比較長)。最后,tenuredgeneration滿之后觸發majorcollection。majorcollection(Fullgc)會觸發整個heap的回收,包括回收younggeneration。permanetgeneration區域比較穩定,主要存放classloader信息。
younggeneration有eden、2個survivor區域組成。其中一個survivor區域一直是空的,是eden區域和另一個survivor區域在下一次copycollection后活著的objecy的目的地。object在survivo區域被復制直到轉移到tenured區。
我們要盡量減少Fullgc的次數(tenuredgeneration一般比較大,收集的時間較長,頻繁的Fullgc會導致應用的性能收到嚴重的影響)。
堆內存GC
JVM(采用分代回收的策略),用較高的頻率對年輕的對象(younggeneration)進行YGC,而對老對象(tenuredgeneration)較少(tenuredgeneration滿了后才進行)進行FullGC。這樣就不需要每次GC都將內存中所有對象都檢查一遍。
非堆內存不GC
GC不會在主程序運行期對PermGenSpace進行清理,所以如果你的應用中有很多CLASS(特別是動態生成類,當然permgenspace存放的內容不僅限于類)的話,就很可能出現PermGenSpace錯誤。
內存申請、對象衰老過程
一、內存申請過程
JVM會試圖為相關Java對象在Eden中初始化一塊內存區域;
當Eden空間足夠時,內存申請結束。否則到下一步;
JVM試圖釋放在Eden中所有不活躍的對象(minorcollection次收集),釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區;
Survivor區被用來作為Eden及old的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區;
當old區空間不夠時,JVM會在old區進行majorcollection(完全收集);
完全垃圾收集后,若Survivor及old區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現"Outofmemory錯誤";
二、對象衰老過程
新創建的對象的內存都分配自eden。Minorcollection的過程就是將eden和在用survivorspace中的活對象copy到空閑survivorspace中。對象在younggeneration里經歷了一定次數(可以通過參數配置)的minorcollection后,就會被移到oldgeneration中,稱為tenuring。
GC觸發條件
GC類型 | 觸發條件 | 觸發時發生了什么 | 注意 | 查看方式 |
YGC | eden空間不足 | 清空Eden+fromsurvivor中所有noref的對象占用的內存 重新調整Eden和from的大小(parallelGC會觸發此項) | 全過程暫停應用 是否為多線程處理由具體的GC決定 | jstat–gcutil gclog |
FGC | old空間不足 | 清空heap中noref的對象 permgen中已經被卸載的classloader中加載的class信息 如配置了CollectGenOFirst,則先觸發YGC(針對serialGC) 如配置了ScavengeBeforeFullGC,則先觸發YGC(針對serialGC) | 全過程暫停應用 是否為多線程處理由具體的GC決定 是否壓縮需要看配置的具體GC | jstat–gcutil gclog |
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。