探究JVM內存泄露時(shí)間:2009-12-03 21:33:26來(lái)源:網(wǎng)絡(luò ) 作者:未知 點(diǎn)擊:659次
WEB服務(wù)總是莫名其妙的運行一段時(shí)間后JVM直接OutOfMemory錯誤,內存泄漏的問(wèn)題不容易查找,本文就一些查找內存泄露基本知識做個(gè)總結,未涉及到具體案例的分析。
WEB服務(wù)總是莫名其妙的運行一段時(shí)間后JVM直接OutOfMemory錯誤,內存泄漏的問(wèn)題不容易查找,本文就一些查找內存泄露基本知識做個(gè)總結,未涉及到具體案例的分析。
1 JVM內存異常的數據顯示
1.1 java.lang.OutOfMemoryError: PermGen space異常的例子
Heap
PSYoungGen total 44928K, used 916K [0x4e3c0000, 0x50fe0000, 0x51b10000)
eden space 44736K, 2% used [0x4e3c0000,0x4e4a5318,0x50f70000)
from space 192K, 0% used [0x50f70000,0x50f70000,0x50fa0000)
to space 192K, 0% used [0x50fb0000,0x50fb0000,0x50fe0000)
PSOldGen total 453312K, used 125529K [0x32910000, 0x4e3c0000, 0x4e3c0000)
object space 453312K, 27% used [0x32910000,0x3a3a6498,0x4e3c0000)
PSPermGen total 65536K, used 65535K [0x2e910000, 0x32910000, 0x32910000)
object space 65536K, 99% used [0x2e910000,0x3290fff8,0x32910000)
permanent space持久空間: 用于類(lèi)和方法對象的存儲。spring在A(yíng)OP時(shí)使用CBLIB會(huì )動(dòng)態(tài)產(chǎn)生很多類(lèi),當類(lèi)太多,超過(guò)MaxPermSize的時(shí)候,就會(huì )拋出此異常。參數問(wèn)題可以設置jvm啟動(dòng)參數: PermSize, MaxPermSize。程序問(wèn)題就要進(jìn)行內存分析了,詳見(jiàn)下文。
1.2 java.lang.OutOfMemoryError: Java heap space異常的例子
Heap
PSYoungGen total 88320K, used 67673K [0x44880000, 0x4ba40000, 0x4ba40000)
eden space 61952K, 100% used [0x44880000,0x48500000,0x48500000)
from space 26368K, 21% used [0x48500000,0x48a96490,0x49ec0000)
to space 24512K, 16% used [0x4a250000,0x4a6283e0,0x4ba40000)
PSOldGen total 932096K, used 582090K [0x0ba40000, 0x44880000, 0x44880000)
object space 932096K, 62% used [0x0ba40000,0x2f2b2a78,0x44880000)
PSPermGen total 131072K, used 35124K [0x03a40000, 0x0ba40000, 0x0ba40000)
object space 131072K, 26% used [0x03a40000,0x05c8d330,0x0ba40000)
eden space使用率100%,總是被占滿(mǎn),參數問(wèn)題可以設置jvm啟動(dòng)參數: Xms, Xmx。程序問(wèn)題就要進(jìn)行內存分析了,詳見(jiàn)下文。
1.3 查看jvm內存狀態(tài):
jstat -gcutil pid 1000 20
異常情況的例子
jstat -gcutil pid 1000 20
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 99.99 82.51 53.11 2409 1.205 10117 7250.393 7251.598
0.00 0.00 83.42 82.55 53.10 2409 1.205 10118 7252.650 7253.855
0.00 0.00 56.06 82.46 53.10 2410 1.205 10120 7254.467 7255.672
0.00 0.00 32.11 82.55 53.10 2411 1.205 10121 7256.673 7257.877
0.00 0.00 99.99 82.55 53.10 2412 1.205 10123 7257.026 7258.231
0.00 0.00 76.00 82.50 53.10 2412 1.205 10124 7259.241 7260.446
這個(gè)數據顯示Full GC頻繁發(fā)生。
正常情況的例子
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
0.00 0.00 0.24 55.39 99.60 171 0.667 1339 393.364 394.031
參數含義:
S0:Heap上的 Survivor space 0 段已使用空間的百分比
S1:Heap上的 Survivor space 1 段已使用空間的百分比
E: Heap上的 Eden space 段已使用空間的百分比
O: Heap上的 Old space 段已使用空間的百分比
P: Perm space 已使用空間的百分比
YGC:從程序啟動(dòng)到采樣時(shí)發(fā)生Young GC的次數
YGCT:Young GC所用的時(shí)間(單位秒)
FGC:從程序啟動(dòng)到采樣時(shí)發(fā)生Full GC的次數
FGCT:Full GC所用的時(shí)間(單位秒)
GCT:用于垃圾回收的總時(shí)間(單位秒)
2 Dump出內存
2.1 找出要dump的線(xiàn)程pid
在windows下,使用tasklist
在Linux下,使用ps –aux
2.2 Dump出內存使用詳情
可以通過(guò)命令:
jmap -dump:file=a.hprof pid
也可以通過(guò)jconsole的圖形界面操作。
在命令行鍵入:jconsole
Jconsole 打開(kāi)后在造作下選擇dumpHeap, 輸入參數p0,p1;p0表示dump出來(lái)的文件路徑,后綴為.hprof; p1設為true,表示只分析活著(zhù)的對象。
3 使用內存分析工具
目前有很多用來(lái)分析Java內存對象的工具,如收費的工具有jprofiler, 而像Eclipse MAT則是優(yōu)秀的內存對象分析開(kāi)源工具.它們對于分析內存溢出問(wèn)題非常有用。以下是一個(gè)安裝使用Eclipse MAT的簡(jiǎn)單例子。
3.1 裝一個(gè)Eclipse的內存分析插件MAT
http://download.eclipse.org/technology/mat/latest/update-site/
3.2 切換到Memory Analysis模式
3.3 通過(guò)File > Open Heap Dump....查看dump出來(lái)的文件
4 JDK自帶的JVM查看分析工具jps、jmap、jstat、jconsole
4.1 jps
Java進(jìn)程查看工具,實(shí)際上它和Unix/Linux上面的ps命令的功能差不多
4.2 jmap
jmap是一個(gè)可以輸出所有內存中對象的工具.
* -dump:format=b,file=<filename> 轉存堆內存到本地文件。
* -histo 打印堆里每個(gè)類(lèi)的情況,包含內存占用大小、對象數量及完整類(lèi)名。VM的內部類(lèi)以"*"開(kāi)頭。
例子:
jmap -histo pid>a.log
jmap -dump: file=a.hprof pid
查看a.log
num #instances #bytes class name
--------------------------------------
1: 427398 14458448 [I
2: 178798 6830216 [C
3: 50278 6668512 <constMethodKlass>
4: 179924 4318176 java.lang.String
5: 50278 4026648 <methodKlass>
6: 15244 3894200 [B
7: 47809 1773776 [Ljava.lang.Object;
...
Total 1645187 81806088
說(shuō)明:
#instance是對象的實(shí)例個(gè)數
#bytes是總占用的字節數
class name對應的就是Class文件里的class的標識
B代表byte
C代表char
D代表double
F代表float
I代表int
J代表long
Z代表boolean
前邊有[代表數組,[I 就相當于int[]
對象用[L+類(lèi)名表示
4.3 jstat
jstat是vm的狀態(tài)監控工具,監控的內容有類(lèi)加載、運行時(shí)編譯及GC。
使用時(shí),需加上查看進(jìn)程的進(jìn)程id,和所選參數。以下詳細介紹各個(gè)參數的意義。
jstat -class pid:顯示加載class的數量,及所占空間等信息。
jstat -compiler pid:顯示VM實(shí)時(shí)編譯的數量等信息。
jstat -gc pid:可以顯示gc的信息,查看gc的次數,及時(shí)間。其中最后五項,分別是young gc的次數,young gc的時(shí)間,full gc的次數,full gc的時(shí)間,gc的總時(shí)間。
jstat -gccapacity:可以顯示,VM內存中三代(young,old,perm)對象的使用和占用大小,如:PGCMN顯示的是最小perm的內存使用量,PGCMX顯示的是perm的內存最大使用量,PGC是當前新生成的perm內存占用量,PC是但前perm內存占用量。其他的可以根據這個(gè)類(lèi)推, OC是old內純的占用量。
jstat -gcnew pid:new對象的信息。
jstat -gcnewcapacity pid:new對象的信息及其占用量。
jstat -gcold pid:old對象的信息。
jstat -gcoldcapacity pid:old對象的信息及其占用量。
jstat -gcpermcapacity pid: perm對象的信息及其占用量。
jstat -util pid:統計gc信息統計。
jstat -printcompilation pid:當前VM執行的信息。
除了以上一個(gè)參數外,還可以同時(shí)加上 兩個(gè)數字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,還可以加上-h3每三行顯示一下標題。
例子:
jstat -gcutil pid 1000 20
4.4 jconsole
一個(gè)java GUI監視工具,可以以圖表化的形式顯示各種數據。并可通過(guò)遠程連接監視遠程的服務(wù)器VM。
本篇文章來(lái)源于:開(kāi)發(fā)學(xué)院 http://edu.codepub.com 原文鏈接:http://edu.codepub.com/2009/1203/18447.php
聯(lián)系客服