JVM系列二 GC策略 記憶體申請 物件衰老

2022-09-16 00:18:13 字數 2770 閱讀 1142

jvm裡的gc(garbage collection)的演算法有很多種,如標記清除收集器,壓縮收集器,分代收集器等等,詳見hotspot vm gc 的種類

現在比較常用的是分代收集(generational collection,也是sun vm使用的,j2se1.2之後引入),即將記憶體分為幾個區域,將不同生命週期的物件放在不同區域裡:young generation,tenured 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資訊。

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都將記憶體中所有物件都檢查一遍。

非堆記憶體不gc

gc不會在主程式執行期對permgen space進行清理,所以如果你的應用中有很多class(特別是動態生成類,當然permgen space存放的內容不僅限於類)的話,就很可能出現permgen space錯誤。

記憶體申請、物件衰老過程

一、記憶體申請過程

jvm會試圖為相關j**a物件在eden中初始化一塊記憶體區域;

當eden空間足夠時,記憶體申請結束。否則到下一步;

jvm試圖釋放在eden中所有不活躍的物件(minor collection),釋放後若eden空間仍然不足以放入新物件,則試圖將部分eden中活躍物件放入survivor區;

survivor區被用來作為eden及old的中間交換區域,當old區空間足夠時,survivor區的物件會被移到old區,否則會被保留在survivor區;

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

完全垃圾收集後,若survivor及old區仍然無法存放從eden複製過來的部分物件,導致jvm無法在eden區為新物件建立記憶體區域,則出現"out of memory錯誤";

二、物件衰老過程

新建立的物件的記憶體都分配自eden。minor collection的過程就是將eden和在用survivor space中的活物件copy到空閒survivor space中。物件在young generation裡經歷了一定次數(可以通過引數配置)的minor collection後,就會被移到old generation中,稱為tenuring。

gc觸發條件gc型別觸發條件觸發時發生了什麼注意檢視方式

ygceden空間不足

清空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

fgcold空間不足

perm空間不足

顯示呼叫system.gc, rmi等的定時觸發

ygc時的悲觀策略

dump live的記憶體資訊時(jmap –dump:live)

清空heap中no ref的物件

permgen中已經被解除安裝的classloader中載入的class資訊

如配置了collectgenofirst,則先觸發ygc(針對serial gc)

如配置了sc**engebeforefullgc,則先觸發ygc(針對serial gc)

全過程暫停應用

是否為多執行緒處理由具體的gc決定

是否壓縮需要看配置的具體gc

jstat –gcutil

gc log

permanent generation空間不足會引發full gc,仍然不夠會引發permgen space錯誤。

參考:gc悲觀策略之parallel gc篇

gc悲觀策略之serial gc篇

jvm記憶體組成 GC

1.jvm記憶體組成 堆 除基本型別之外所有new的物件儲存在堆。棧 儲存一些區域性變數 臨時儲存 本地方法棧 只要支援其他語言的方法,儲存native方法的狀態 方法區 存放類資訊,靜態資訊,final常量資訊,屬性,方法等。主要存放於持久代。程式計數器 pc 2.堆是由新生代和舊生代組成,new...

JVM記憶體結構與GC

前段時間沒有好好準備,錯過了 金三銀四 因此最近開始惡補各方面知識,決定先從jvm記憶體結構和gc開始。jvm記憶體結構分為如下幾部分 前兩項為執行緒共享,後三項為執行緒私有的 1 方法區 儲存已經被虛擬機器載入的類資訊 常量 jit 及時編譯器just in time 編譯後的 以及類變數 sta...

JVM系列之Trace跟蹤GC(一)

首先,我們需要創造乙個gc 的條件,正常而言,還真難創造出來。所以,我們必須借助jvm啟動引數。無容置疑,堆空間大小的引數無非就是xms和xmx。xms jvm堆空間初始大小,這不是我們想要的 xmx jvm最大堆空間,這個才是我們需要的 注 xmx引數不宜過小,過小的堆空間會導致jvm無法啟動,極...