
通過(guò)這個(gè)看啟動(dòng)參數,java jvm 參數 -Xms -Xmx -Xmn -Xss 調優(yōu)總結
-Xms初始Heap大小,-Xmx Heap最大值,一般設置一樣大
PermSize表示持久帶
-Xmn設置年輕帶大小
-Xss128k:設置每個(gè)線(xiàn)程的堆棧大小.JDK5.0以后每個(gè)線(xiàn)程堆棧大小為1M,以前每個(gè)線(xiàn)程堆棧大小為256K
-XX:SurvivorRatio=4:設置年輕代中Eden區與Survivor區的大小比值.設置為4,則兩個(gè)Survivor區與一個(gè)Eden區的比值為2:4,一個(gè)Survivor區占整個(gè)年輕代的1/6
-XX:NewRatio=4:設置年輕代(包括Eden和兩個(gè)Survivor區)與年老代的比值(除去持久代).設置為4,則年輕代與年老代所占比值為1:4,年輕代占整個(gè)堆棧的1/5
XX:CMSInitiatingOccupancyFraction=80,當old space的空間占用達到80%后會(huì )強制JVM執行CMS。
XX:+CMSClassUnloadingEnabled允許CMS回收永久代的不可到達對象, 默認情況下,JVM的CMS是不會(huì )去回收永久代的對象,
-XX:+UseCMSCompactAtFullCollection:使用并發(fā)收集器時(shí),開(kāi)啟對年老代的壓縮。
admin 6758 70.2 64.0 6492928 4915416 ? SNl Apr20 5605:40 /opt/java/bin/java -Dprogram.name=run.sh -server -Xms4g -Xmx4g -XX:PermSize=96m -XX:MaxPermSize=256m -Xmn2560m -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSMaxAbortablePrecleanTime=5000 -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:+DisableExplicitGC -verbose:gc -Xloggc:/home/XXX/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseCompressedOops -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=10000 -Dsun.net.client.defaultReadTimeout=30000 -Djava.net.preferIPv4Stack=true -Djava.endorsed.dirs=/opt/taobao/jboss/lib/endorsed -classpath /opt/taobao/jboss/bin/run.jar:/opt/taobao/java/lib/tools.jar org.jboss.Main -b 0.0.0.0 -Djboss.server.home.dir=/home/admin/xu/.default -Djboss.server.home.url=file:/home/admin/xu/.default
How to Monitor Java Garbage Collection
-verbose:gc可以顯示堆和gc的一些信息,比如:
[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]
兩次minor gc之后發(fā)生了一次full gc,325407K->83000K表明gc之前存活的對象大小,以及gc后的大小,776768表示不再使用被回收的對象,0.2300771sec表示執行回收的時(shí)間,
使用-XX:+PrintGCDetails參數,可以增加更多的信息,比如
[GC [DefNew: 64575K->959K(64576K), 0.0457646 secs] 196016K->133633K(261184K), 0.0459067 secs]
表明minor gc回收了98%的空間,從64575K到959K,花費了0.0457sec,整個(gè)堆減少了51%,從196016K->133633K(261184K)到,猜測應該是包括了部分從young拷貝對象到tenued的時(shí)間,稍有增加,為0.0459sec
-XX:+PrintGCTimeStamps參數會(huì )在gc開(kāi)始前添加時(shí)間戳,可以方便的判斷gc發(fā)送的頻率
111.042: [GC 111.042: [DefNew: 8128K->8128K(8128K), 0.0000505 secs]111.042: [Tenured: 18154K->2311K(24576K), 0.1290354 secs] 26282K->2311K(32704K), 0.1293306 secs]
發(fā)生minor gc的同時(shí)還發(fā)生了major gc
2012-12-19T13:58:18.122+0800: 13197.398: [GC 13197.398: [ParNew: 752045K->16071K(829440K), 0.0574310 secs] 2119069K->1384051K(4102144K), 0.0576820 secs] [Times: user=0.20 sys=0.00, real=0.05 secs]
[1] real : 表示foo程序整個(gè)的運行耗時(shí),可以理解運行開(kāi)始時(shí)刻你看了一下手表,運行結束時(shí),你又看了一下手表,兩次時(shí)間的差值就是本次real 代表的值
User 是在用戶(hù)態(tài)下的CPU時(shí)間總和
Sys 是內核態(tài)下的CPU時(shí)間總和
User+Sys表示總共的CPU利用時(shí)間,除以real可以得出CPU利用率
誤區一: real_time = user_time + sys_time
我們錯誤的理解為,real time 就等于 user time + sys time,這是不對的,real time是時(shí)鐘走過(guò)的時(shí)間,user time 是程序在用戶(hù)態(tài)的cpu時(shí)間,sys time 為程序在核心態(tài)的cpu時(shí)間。
利用這三者,我們可以計算程序運行期間的cpu利用率如下:
%cpu_usage = (user_time + sys_time)/real_time * 100%
如:
# time sleep 2
real 0m2.003s
user 0m0.000s
sys 0m0.000s
cpu利用率為0,因為本身就是這樣的,sleep 了2秒,時(shí)鐘走過(guò)了2秒,但是cpu時(shí)間都為0,所以利用率為0
誤區二:real_time > user_time + sys_time
一般來(lái)說(shuō),上面是成立的,上面的情況在單cpu的情況下,往往都是對的。
但是在多核cpu情況下,而且代碼寫(xiě)的確實(shí)很漂亮,能把多核cpu都利用起來(lái),那么這時(shí)候上面的關(guān)系就不成立了,例如可能出現下面的情況,請不要驚奇。
real 1m47.363s
user 2m41.318s
sys 0m4.013s
調優(yōu)
到目前為止調優(yōu)兩次
一次是因為相同內存配置的兩個(gè)應用,有一個(gè)應用的minor gc時(shí)間遠遠大于另一個(gè)應用,不解,因此就想著(zhù)調笑young之類(lèi)的,但是調小了gc次數也變多了,整體停頓時(shí)間可能沒(méi)相差太多;還試過(guò)parallel scavenge的自動(dòng)調整策略,限制minor gc時(shí)間在40ms以下,他就是調小了young,也沒(méi)什么特別
另一次是發(fā)現每次minor gc之后總有對象晉升到old區,開(kāi)始以為是survivor太小,也看過(guò)晉升閥值在4次左右,因此就調大了survivor,但是發(fā)現cms gc反而頻繁了,估計是因為old變小的緣故;調大了survivor之后,并不是每次mior gc都有對象晉升,但是觀(guān)察發(fā)現到后面第14,15次拷貝的時(shí)間,對象已經(jīng)基本沒(méi)有減少(最多減少1K左右),剩余的大部分對象都只是在重復拷貝罷了
這也可能和我們的應用有關(guān),我們的緩存會(huì )保留比較長(cháng)的時(shí)間(起碼10分鐘),所以調大survivor也只是白白浪費時(shí)間
總的來(lái)說(shuō),兩次調優(yōu)都以失敗告終,fuck?。?!
聯(lián)系客服