網絡上有很多文檔,我也抄記很多內容到有道去筆記,可是那些東西都是別人的,
只通過消化測試總結纔算是自己的內容,所以我也抄襲一下吧.
先上傳一張圖, 主要是對JVM GC收集器的對比說明,根據鏈接內容,做出自己的理解.
http://hllvm.group.iteye.com/group/topic/37095此鏈接的內容對我很我幫助.
# cat gccheck.sh #!/bin/bash #沒有註釋 20150916 filename="/data/resin/log/jvm-app-a.log" thistime=0.0 lasttime=0.0 tail -100 $filename | awk '/\[GC/' | while read line do echo $line | egrep -q 'CMS-initial-mark|YG occupancy' if [ $? -eq 0 ];then echo $line | awk '/CMS-initial-mark/{printf "%d %s %s, ",$1/60,$1,$(NF-1)};/YG occupancy/{print $1,$(NF-1)}' continue fi midline=$(echo $line | sed 's#\[##g;s#\]##g;s#:##g;s#(# #g;s#)##g;s#,##g;s#K##g;s#-># #g;') rate=$(echo $midline | awk '{printf "%.0f\n",($10-$7)/($12-$7)*100}') ygk=$(echo $midline | awk '{printf "%d\n",$5-$6}') heapk=$(echo $midline | awk '{printf "%d\n",$10-$11}') thistime=$(echo $midline | awk '{print $3}') interval=$(echo "$thistime-$lasttime"|bc) usedtime=$(echo $midline | awk '{printf "%d\n",$8*1000}') let total=ygk-heapk if [ $total -gt 0 ];then echo -e "YG減少的數據量 $ygk HEAP堆減少量 $heapk \033[31m間隔時間爲 $interval 持續時間爲 $usedtime 轉移內容到OG爲+$total KB \033[0m當前OG佔有率 $rate%" else echo -e "YG減少的數據量 $ygk HEAP堆減少量 $heapk \033[31m間隔時間爲 $interval 持續時間爲 $usedtime 轉移內容到OG爲-$total KB\033[0m當前OG佔有率 $rate%" fi lasttime=$thistime sleep 0.05 done
也是抄別人的,自己改了一下,主要是對GC回收過去進行查看.
13449.991: [GC 13449.991: [ParNew: 344566K->17482K(368640K), 0.0272580 secs] 734079K->407266K(1495040K), 0.0274010 secs] [Times: user=0.10 sys=0.01, real=0.03 secs]
13488.107: [GC 13488.107: [ParNew: 345162K->17620K(368640K), 0.0378120 secs] 734946K->410438K(1495040K), 0.0379860 secs] [Times: user=0.13 sys=0.00, real=0.03 secs]
13516.941: [GC 13516.941: [ParNew: 345300K->12992K(368640K), 0.0198980 secs] 738118K->406392K(1495040K), 0.0200320 secs] [Times: user=0.07 sys=0.00, real=0.02 secs]
簡單腳本分析,通過打印日誌瞭解JVM回收健康情況,抄抄改改.
可以瞭解到每次YGC的垃圾回收和對象實例轉移情況, 我認爲間隔35秒,YGC持續25秒左右的
哎呀,這個腳本還有修改一下.
執行 bash gccheck.sh會產生以下可視化內容.
YG減少的數據量 327084 HEAP堆減少量 326813 間隔時間爲 36.019 持續時間爲 27 轉移內容到OG爲+271 KB 當前OG佔有率 32%
YG減少的數據量 327542 HEAP堆減少量 324508 間隔時間爲 38.116 持續時間爲 37 轉移內容到OG爲+3034 KB 當前OG佔有率 33%
YG減少的數據量 332308 HEAP堆減少量 331726 間隔時間爲 28.834 持續時間爲 19 轉移內容到OG爲+582 KB 當前OG佔有率 33%
############################################################
經過對網上內容的抄襲,終於得出這樣的配置內容.
<jvm-arg>-Xms1500m</jvm-arg>
<jvm-arg>-Xmx1500m</jvm-arg>
<jvm-arg>-Xmn400m</jvm-arg>
<jvm-arg>-XX:SurvivorRatio=8</jvm-arg>
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg>
<jvm-arg>-XX:+CMSParallelRemarkEnabled</jvm-arg>
<jvm-arg>-XX:+UseCMSCompactAtFullCollection</jvm-arg>
<jvm-arg>-XX:CMSInitiatingOccupancyFraction=80</jvm-arg>
<jvm-arg>-XX:+UseCMSInitiatingOccupancyOnly</jvm-arg>
<jvm-arg>-XX:MaxDirectMemorySize=1024m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=256m</jvm-arg>
<jvm-arg>-XX:PermSize=128m</jvm-arg>
<jvm-arg>-XX:+PrintGCTimeStamps</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xss512k</jvm-arg>
<jvm-arg>-Xms1500m</jvm-arg> #heap堆設置爲1.5G,OG就可以剩下1.1G, 通過調用CMS提高收集速率,當到達(OG的80%容量)
<jvm-arg>-Xmx1500m</jvm-arg> #880M的時候,就可以進行FGC處理,可以達到70秒左右(初始標記+並行掃描壓縮)
<jvm-arg>-Xmn400m</jvm-arg> #剛開始設置512M,後來調整400MB,使其每隔35秒進行一次YG,單次YG時間爲20秒左右
<jvm-arg>-XX:SurvivorRatio=8</jvm-arg> #有時會觀察到survivor比例不一致,顯示設置爲8
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg> #使用CMS進行OG內存回收,對應會使用ParNew進行YG回收
<jvm-arg>-XX:+CMSParallelRemarkEnabled</jvm-arg> #第三階段remark使用並行標記,減少停工時間 注意併發和並行
<jvm-arg>-XX:+UseCMSCompactAtFullCollection</jvm-arg> #CMS默認沒有壓縮,此處調用避免碎片,CMS-concurrent-sweep階段
<jvm-arg>-XX:CMSInitiatingOccupancyFraction=80</jvm-arg> #等到OG使用率達到80%的時候開始收集
<jvm-arg>-XX:+UseCMSInitiatingOccupancyOnly</jvm-arg> #OG必須達到80%才調用CMS進行FGC收集
<jvm-arg>-XX:MaxDirectMemorySize=1024m</jvm-arg> #應用會調用NIO進行內容分配,我會強制限定使用1G
<jvm-arg>-XX:MaxPermSize=256m</jvm-arg> #PG最大空間,最大擴展範圍
<jvm-arg>-XX:PermSize=128m</jvm-arg> #靜態對象 變量存在空間,此處爲128M,一般讓其維持在50%使用
<jvm-arg>-XX:+PrintGCTimeStamps</jvm-arg> #必須打印出日誌進行分析
<jvm-arg>-XX:+PrintGCDetails</jvm-arg> #必須打印出日誌進行分析
<jvm-arg>-Xss512k</jvm-arg> #線程實例由之前1M調整爲512K, 降低單支成本,提高產量
命令查看jvm信息,jmap jstat
#以下是jstat打印GC回收情況,那個FGCT爲2是剛啓動應用時出現些問題,穩定一天左右就會迴歸到70ms左右.
#另外那個YGC大約維持25ms左右,我覺得已經很贊,我的水平就是這樣.
# /usr/java/jdk/bin/jstat -gcutil -h30 8828 1s
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 35.76 85.10 36.73 50.36 421 10.026 2 1.654 11.680
0.00 35.76 90.37 36.73 50.36 421 10.026 2 1.654 11.680
0.00 35.76 92.28 36.73 50.36 421 10.026 2 1.654 11.680
35.39 0.00 0.34 36.78 50.36 422 10.050 2 1.654 11.704
35.39 0.00 2.51 36.78 50.36 422 10.050 2 1.654 11.704
35.39 0.00 4.96 36.78 50.36 422 10.050 2 1.654 11.704
----------------------------------------------------------------------------------------------
# /usr/java/jdk/bin/jmap -heap 8828
Attaching to process ID 8828, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.7-b02
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1572864000 (1500.0MB)
NewSize = 419430400 (400.0MB)
MaxNewSize = 419430400 (400.0MB)
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 134217728 (128.0MB)
MaxPermSize = 268435456 (256.0MB)
#一將功成萬骨枯,java程序內存資源很寶貴......
Heap Usage:
New Generation (Eden + 1 Survivor Space): #一個eden區和兩個S區(兩者只能存在一個),實際可用NG爲360MB
capacity = 377487360 (360.0MB)
used = 140504056 (133.99510955810547MB)
free = 236983304 (226.00489044189453MB)
37.22086376614041% used
Eden Space: #E區使用情況
capacity = 335544320 (320.0MB)
used = 125658376 (119.83716583251953MB)
free = 209885944 (200.16283416748047MB)
37.44911432266235% used
From Space: #此處S區from空間分配爲1:1:8,實際爲10%(400MB),最後是40MB,可是有時不會得到這個值.
capacity = 41943040 (40.0MB)
used = 14845680 (14.157943725585938MB)
free = 27097360 (25.842056274414062MB)
35.394859313964844% used
To Space: #同上
capacity = 41943040 (40.0MB)
used = 0 (0.0MB)
free = 41943040 (40.0MB)
0.0% used
concurrent mark-sweep generation: #以前調整的時候,總會遇到內存碎片,這次終於正常了,呵呵.
capacity = 1153433600 (1100.0MB)
used = 424188544 (404.5377197265625MB)
free = 729245056 (695.4622802734375MB)
36.77615633877841% used
Perm Generation: #根據上面的配置,PG一般會維持在50%左右,我這次分配128MB
capacity = 134217728 (128.0MB)
used = 67596336 (64.46488952636719MB)
free = 66621392 (63.53511047363281MB)
50.363194942474365% used
----------------------------------------------------------------------------------------------
優化結果和跟進
----------------------------------------------------------------------------------------------
說明64位VM機器和JDK,內存4G
1.resin jvm1.5G(400+1100),mc緩存分配1G,爲提高信息讀寫速度使用NIO技術,
使用bytebuffer. allocate分配內在,此處DirectMemorySize也最大設置爲1G.
2. 通過free -m瞭解到SWAP還是有731M在使用,實際想不到是哪個進程在使用.
ps aux結果爲以下內容
java區RES1.2G爲heap堆部分,swap部分應該爲nio bytebuffer使用的1G加速空間.
mc區分配1G空間,數據跳出率很高,此處swap 468M應該是MC的影響.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP DATA COMMAND
8828 xxx 15 0 2282m 1.2g 12m S 6.7 31.4 37:31.03 1.0g 2.1g java
4128 yyy 15 0 1307m 839m 560 S 2.3 21.2 5445:57 468m 1.3g memcached
3.MC的狀態信息 主要還是覺得有必要優化一下MC,學學學
curr_items 399754 現在的條目只有40萬條
total_items 418833290 總共活躍條目4.1億次
evictions 148384635 數據跳出率1.4億次
RunDays 140 days
Items 399754
MaxMem 1024 MByte
Usage 57.20 %
HitRate 86.23 %
以下爲MC的資源池分配情況,group 29 30佔用過多資源,導致group 8 9次沒有資源使用,結果消耗系統swap資源.
# xmemcached.pl localhost:11211
# Item_Size Max_age 1MB_pages Count Full?
8 480 B 15067 s 27 58853 yes
9 600 B 29830 s 33 57651 yes
10 752 B 8255 s 28 39032 yes
29 51.7 kB 29275 s 742 8263 yes
30 64.7 kB 3095 s 138 857 yes
標記:優化其應用,通過控制jvm大小和算法來優化,當然找到內存泄漏代碼並解決問題纔是最重要.
可是目前只會這樣,通過此文希望能再接再勵吧.
感覺以下鏈接內容:
http://www.iteye.com/topic/212967
http://www.iteye.com/topic/212967
http://www.iteye.com/topic/473874
http://blog.csdn.net/fenglibing/article/details/6321453
http://hllvm.group.iteye.com/group/topic/27945