JVM內(nèi)存設(shè)置

問題

一個新上線java服務(wù)贮乳, 內(nèi)存的設(shè)置該怎么設(shè)置呢恬惯?設(shè)置成多大比較合適酪耳,既不浪費內(nèi)存,又不影響性能呢颈将?

分析:
依據(jù)的原則是根據(jù)Java Performance里面的推薦公式來進(jìn)行設(shè)置晴圾。

image.png

具體來講:
Java整個堆大小設(shè)置死姚,Xmx 和 Xms設(shè)置為老年代存活對象的3-4倍,即FullGC之后的老年代內(nèi)存占用的3-4倍
永久代 PermSize和MaxPermSize設(shè)置為老年代存活對象的1.2-1.5倍”M停【永久區(qū)并不是老年代的1.2到1.5倍,而是FullGC后永久區(qū)的1.2到1.5倍 1.2x to 1.5x permanent generation space】
年輕代Xmn的設(shè)置為老年代存活對象的1-1.5倍竟终。
老年代的內(nèi)存大小設(shè)置為老年代存活對象的2-3倍。

BTW:
1喘鸟、Sun官方建議年輕代的大小為整個堆的3/8左右, 所以按照上述設(shè)置的方式崎淳,基本符合Sun的建議拣凹。
2嚣镜、堆大小=年輕代大小+年老代大小祈惶, 即xmx=xmn+老年代大小 捧请。 Permsize不影響堆大小疹蛉。
3可款、為什么要按照上面的來進(jìn)行設(shè)置呢? 沒有具體的說明闺鲸,但應(yīng)該是根據(jù)多種調(diào)優(yōu)之后得出的一個結(jié)論。

如何確認(rèn)老年代存活對象大辛⑾狻?
方式1(推薦/比較穩(wěn)妥):
JVM參數(shù)中添加GC日志类早,GC日志中會記錄每次FullGC之后各代的內(nèi)存大小缭召,觀察老年代GC之后的空間大小嵌巷。可觀察一段時間內(nèi)(比如2天)的FullGC之后的內(nèi)存情況蛙卤,根據(jù)多次的FullGC之后的老年代的空間大小數(shù)據(jù)來預(yù)估FullGC之后老年代的存活對象大小(可根據(jù)多次FullGC之后的內(nèi)存大小取平均值)

方式2:(強(qiáng)制觸發(fā)FullGC, 會影響線上服務(wù)已维,慎用)
方式1的方式比較可行行嗤,但需要更改JVM參數(shù),并分析日志垛耳。同時栅屏,在使用CMS回收器的時候,有可能不能觸發(fā)FullGC(只發(fā)生CMS GC)堂鲜,所以日志中并沒有記錄FullGC的日志栈雳。在分析的時候就比較難處理。
BTW:使用jstat -gcutil工具來看FullGC的時候缔莲, CMS GC是會造成2次的FullGC次數(shù)增加哥纫。 具體可參見之前寫的一篇關(guān)于jstat使用的文章
所以,有時候需要強(qiáng)制觸發(fā)一次FullGC痴奏,來觀察FullGC之后的老年代存活對象大小蛀骇。
注:強(qiáng)制觸發(fā)FullGC暑诸,會造成線上服務(wù)停頓(STW)伞矩,要謹(jǐn)慎,建議的操作方式為,在強(qiáng)制FullGC前先把服務(wù)節(jié)點摘除,F(xiàn)ullGC之后再將服務(wù)掛回可用節(jié)點,對外提供服務(wù)
在不同時間段觸發(fā)FullGC,根據(jù)多次FullGC之后的老年代內(nèi)存情況來預(yù)估FullGC之后的老年代存活對象大小

如何觸發(fā)FullGC ?
使用jmap工具可觸發(fā)FullGC
jmap -dump:live,format=b,file=heap.bin <pid> 將當(dāng)前的存活對象dump到文件拾氓,此時會觸發(fā)FullGC
jmap -histo:live <pid> 打印每個class的實例數(shù)目,內(nèi)存占用,類全名信息.live子參數(shù)加上后,只統(tǒng)計活的對象數(shù)量. 此時會觸發(fā)FullGC

具體操作實例:
以我司的一個RPC服務(wù)為例奶陈。
BTW:剛上線的新服務(wù)徐勃,不知道該設(shè)置多大的內(nèi)存的時候,可以先多設(shè)置一點內(nèi)存冀自,然后根據(jù)GC之后的情況來進(jìn)行分析驻呐。
初始JVM內(nèi)存參數(shù)設(shè)置為: Xmx=2G Xms=2G xmn=1G

使用jstat 查看當(dāng)前的GC情況绣张。如下圖:

image

YGC平均耗時: 173.825s/15799=11ms
FGC平均耗時:0.817s/41=19.9ms
平均大約10-20s會產(chǎn)生一次YGC

看起來似乎不錯,YGC觸發(fā)的頻率不高,F(xiàn)GC的耗時也不高奔浅,但這樣的內(nèi)存設(shè)置是不是有些浪費呢?
為了快速看數(shù)據(jù),我們使用了方式2,產(chǎn)生了幾次FullGC菠红,F(xiàn)ullGC之后遇绞,使用的jmap -heap 來看的當(dāng)前的堆內(nèi)存情況(也可以根據(jù)GC日志來看)
heap情況如下圖:(命令 : jmap -heap <pid>)

image

上圖中的concurrent mark-sweep generation即為老年代的內(nèi)存描述付鹿。
老年代的內(nèi)存占用為100M左右徽诲。 按照整個堆大小是老年代(FullGC)之后的3-4倍計算的話,設(shè)置各代的內(nèi)存情況如下:
Xmx=512m Xms=512m Xmn=128m PermSize=128m 老年代的大小為 (512-128=384m)為老年代存活對象大小的3倍左右
調(diào)整之后的硫麻,heap情況

image

GC情況如下:

image

YGC 差不多在10s左右觸發(fā)一次柳洋。每次YGC平均耗時大約9.41ms】奂祝可接受琉挖。
FGC平均耗時:0.016s/2=8ms
整體的GC耗時減少顽耳。但GC頻率比之前的2G時的要多了一些。

注: 看上述GC的時候,發(fā)現(xiàn)YGC的次數(shù)突然會增多很多個,比如 從1359次到了1364次酸舍。具體原因是?

總結(jié):
在內(nèi)存相對緊張的情況下里初,可以按照上述的方式來進(jìn)行內(nèi)存的調(diào)優(yōu)啃勉, 找到一個在GC頻率和GC耗時上都可接受的一個內(nèi)存設(shè)置,可以用較小的內(nèi)存滿足當(dāng)前的服務(wù)需要
但當(dāng)內(nèi)存相對寬裕的時候双妨,可以相對給服務(wù)多增加一點內(nèi)存淮阐,可以減少GC的頻率,GC的耗時相應(yīng)會增加一些刁品。 一般要求低延時的可以考慮多設(shè)置一點內(nèi)存泣特, 對延時要求不高的,可以按照上述方式設(shè)置較小內(nèi)存挑随。

補(bǔ)充:
永久代(方法區(qū))并不在堆內(nèi)状您,所以之前有看過一篇文章中描述的 整個堆大小=年輕代+年老代+永久代的描述是不正確的。

jmap -heap pid 結(jié)果參數(shù)詳解

Debugger attached successfully.
Server compiler detected.
JVM version is 25.171-b11

using thread-local object allocation.
Parallel GC with 8 thread(s) //采用Parallel GC 

Heap Configuration:
   MinHeapFreeRatio         = 0    //JVM最小空閑比率 可由-XX:MinHeapFreeRatio=<n>參數(shù)設(shè)置兜挨, jvm heap 在使用率小于 n 時 ,heap 進(jìn)行收縮
   MaxHeapFreeRatio         = 100  //JVM最大空閑比率 可由-XX:MaxHeapFreeRatio=<n>參數(shù)設(shè)置膏孟, jvm heap 在使用率大于 n 時 ,heap 進(jìn)行擴(kuò)張 
   MaxHeapSize              = 2095054848 (1998.0MB) //JVM堆的最大大小 可由-XX:MaxHeapSize=<n>參數(shù)設(shè)置
   NewSize                  = 44040192 (42.0MB) //JVM新生代的默認(rèn)大小 可由-XX:NewSize=<n>參數(shù)設(shè)置
   MaxNewSize               = 698351616 (666.0MB) //JVM新生代的最大大小 可由-XX:MaxNewSize=<n>參數(shù)設(shè)置
   OldSize                  = 88080384 (84.0MB) //JVM老生代的默認(rèn)大小 可由-XX:OldSize=<n>參數(shù)設(shè)置 
   NewRatio                 = 2 //新生代:老生代(的大小)=1:2 可由-XX:NewRatio=<n>參數(shù)指定New Generation與Old Generation heap size的比例拌汇。
   SurvivorRatio            = 8 //survivor:eden = 1:8,即survivor space是新生代大小的1/(8+2)[因為有兩個survivor區(qū)域] 可由-XX:SurvivorRatio=<n>參數(shù)設(shè)置
   MetaspaceSize            = 21807104 (20.796875MB) //元空間的默認(rèn)大小柒桑,超過此值就會觸發(fā)Full GC 可由-XX:MetaspaceSize=<n>參數(shù)設(shè)置
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //類指針壓縮空間的默認(rèn)大小 可由-XX:CompressedClassSpaceSize=<n>參數(shù)設(shè)置
   MaxMetaspaceSize         = 17592186044415 MB //元空間的最大大小 可由-XX:MaxMetaspaceSize=<n>參數(shù)設(shè)置
   G1HeapRegionSize         = 0 (0.0MB) //使用G1垃圾收集器的時候,堆被分割的大小 可由-XX:G1HeapRegionSize=<n>參數(shù)設(shè)置

Heap Usage:
PS Young Generation //新生代區(qū)域分配情況
Eden Space: //Eden區(qū)域分配情況
   capacity = 89653248 (85.5MB)
   used     = 8946488 (8.532035827636719MB)
   free     = 80706760 (76.96796417236328MB)
   9.978989272089729% used
From Space: //其中一個Survivor區(qū)域分配情況
   capacity = 42467328 (40.5MB)
   used     = 15497496 (14.779563903808594MB)
   free     = 26969832 (25.720436096191406MB)
   36.49275037977431% used
To Space:  //另一個Survivor區(qū)域分配情況
   capacity = 42991616 (41.0MB)
   used     = 0 (0.0MB)
   free     = 42991616 (41.0MB)
   0.0% used
PS Old Generation //老生代區(qū)域分配情況
   capacity = 154664960 (147.5MB)
   used     = 98556712 (93.99100494384766MB)
   free     = 56108248 (53.508995056152344MB)
   63.722715216167906% used

1819 interned Strings occupying 163384 bytes.```
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末噪舀,一起剝皮案震驚了整個濱河市魁淳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌与倡,老刑警劉巖蒸走,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岛抄,死亡現(xiàn)場離奇詭異夫椭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蹭秋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門堤撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來实昨,“玉大人荒给,你說我怎么就攤上這事志电±欤” “怎么了之拨?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵茉继,是天一觀的道長。 經(jīng)常有香客問我派撕,道長氯哮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任姆打,我火速辦了婚禮玛追,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己侍匙,他們只是感情好想暗,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琐旁,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天涮阔,我揣著相機(jī)與錄音,去河邊找鬼灰殴。 笑死敬特,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伟阔,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼辣之,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了减俏?” 一聲冷哼從身側(cè)響起召烂,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娃承,沒想到半個月后奏夫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡历筝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年酗昼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梳猪。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡麻削,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出春弥,到底是詐尸還是另有隱情呛哟,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布匿沛,位于F島的核電站扫责,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逃呼。R本人自食惡果不足惜鳖孤,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抡笼。 院中可真熱鬧苏揣,春花似錦、人聲如沸推姻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拾碌。三九已至吐葱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間校翔,已是汗流浹背弟跑。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留防症,地道東北人孟辑。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓哎甲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饲嗽。 傳聞我的和親對象是個殘疾皇子炭玫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容