經(jīng)驗分享 JVM調(diào)優(yōu)方法總結(jié)
你對JVM調(diào)優(yōu)是否熟悉,這里向大家描述一下,首先要了解幾個概念,比如說Perm持久代,用于存放靜態(tài)文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate等。
JVM調(diào)優(yōu)總結(jié)
Young(年輕代)
年輕代分三個區(qū)。一個Eden區(qū),兩個Survivor區(qū)。大部分對象在Eden區(qū)中生成。當(dāng)Eden區(qū)滿時,還存活的對象將被復(fù)制到Survivor區(qū)(兩個中的一個),當(dāng)這個Survivor區(qū)滿時,此區(qū)的存活對象將被復(fù)制到另外一個Survivor區(qū),當(dāng)這個Survivor去也滿了的時候,從***個Survivor區(qū)復(fù)制過來的并且此時還存活的對象,將被復(fù)制“年老區(qū)(Tenured)”。需要注意,Survivor的兩個區(qū)是對稱的,沒先后關(guān)系,所以同一個區(qū)中可能同時存在從Eden復(fù)制過來對象,和從前一個Survivor復(fù)制過來的對象,而復(fù)制到年老區(qū)的只有從***個Survivor去過來的對象。而且,Survivor區(qū)總有一個是空的。
Tenured(年老代)
年老代存放從年輕代存活的對象。一般來說年老代存放的都是生命期較長的對象。
Perm(持久代)
用于存放靜態(tài)文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate等,在這種時候需要設(shè)置一個比較大的持久代空間來存放這些運行過程中新增的類。持久代大小通過-XX:MaxPermSize=<N>進行設(shè)置。
JVM調(diào)優(yōu)之年輕代大小選擇
◆響應(yīng)時間優(yōu)先的應(yīng)用:盡可能設(shè)大,直到接近系統(tǒng)的***響應(yīng)時間限制(根據(jù)實際情況選擇)。在此種情況下,年輕代收集發(fā)生的頻率也是最小的。同時,減少到達年老代的對象。
◆吞吐量優(yōu)先的應(yīng)用:盡可能的設(shè)置大,可能到達Gbit的程度。因為對響應(yīng)時間沒有要求,垃圾收集可以并行進行,一般適合8CPU以上的應(yīng)用。
JVM調(diào)優(yōu)之年老代大小選擇
◆響應(yīng)時間優(yōu)先的應(yīng)用:年老代使用并發(fā)收集器,所以其大小需要小心設(shè)置,一般要考慮并發(fā)會話率和會話持續(xù)時間等一些參數(shù)。如果堆設(shè)置小了,可以會造成內(nèi)存碎片、高回收頻率以及應(yīng)用暫停而使用傳統(tǒng)的標(biāo)記清除方式;如果堆大了,則需要較長的收集時間。***化的方案,一般需要參考以下數(shù)據(jù)獲得:
1.并發(fā)垃圾收集信息
2.持久代并發(fā)收集次數(shù)
3.傳統(tǒng)GC信息
4.花在年輕代和年老代回收上的時間比例
減少年輕代和年老代花費的時間,一般會提高應(yīng)用的效率
◆吞吐量優(yōu)先的應(yīng)用:一般吞吐量優(yōu)先的應(yīng)用都有一個很大的年輕代和一個較小的年老代。原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活對象。
JVM調(diào)優(yōu)之較小堆引起的碎片問題
因為年老代的并發(fā)收集器使用標(biāo)記、清除算法,所以不會對堆進行壓縮。當(dāng)收集器回收時,他會把相鄰的空間進行合并,這樣可以分配給較大的對象。但是,當(dāng)堆空間較小時,運行一段時間以后,就會出現(xiàn)“碎片”,如果并發(fā)收集器找不到足夠的空間,那么并發(fā)收集器將會停止,然后使用傳統(tǒng)的標(biāo)記、清除方式進行回收。如果出現(xiàn)“碎片”,可能需要進行如下配置:
◆-XX:+UseCMSCompactAtFullCollection:使用并發(fā)收集器時,開啟對年老代的壓縮。
◆-XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設(shè)置多少次FullGC后,對年老代進行壓縮
【編輯推薦】