1宇攻、jdk 自帶基礎工具
2惫叛、MAT 分析dump
3、VM 實時監(jiān)控
4 逞刷、遇到過OOM
內存溢出有哪些
1嘉涌、Java堆溢出 (java.lang.OutofMemoryError:Java heap space)
2、PermGen space
3夸浅、StackOverflowError(虛擬機在擴展棧時無法申請到足夠的內存空間)
4仑最、直接崩潰
內存溢出與泄漏
內存溢出 out of memory:
是指程序在申請內存時,沒有足夠的內存空間供其使用帆喇,出現out of memory警医;
內存泄露 memory leak,
是指程序在申請內存后坯钦,無法釋放已申請的內存空間预皇,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重婉刀,無論多少內存,遲早會被占光
一吟温、jdk 自帶基礎工具
1、 ** jps(Java Virtual Machine Process Status Tool) **
實際中這是最常用的命令突颊,下面要介紹的小工具更多的都是先要使用jps查看出當前有哪些Java進程鲁豪,獲取該Java進程的id后再對該進程進行處理潘悼。
jps [options] [hostid]
-q 不輸出類名、Jar名和傳入main方法的參數
-m 輸出傳入main方法的參數
-l 輸出main類或Jar的全限名
-v 輸出傳入JVM的參數
[root@iZbp11b3erzreb4xi5utvzZ /]# jps -ml
22611 /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war 740 org.apache.catalina.startup.Bootstrap start19942 org.apache.zookeeper.server.quorum.QuorumPeerMain /mnt/zk/zookeeper-3.4.13/bin/../conf/zoo.cfg20537 sun.tools.jps.Jps -ml11309 org.sonatype.nexus.bootstrap.jsw.JswLauncher ./conf/jetty.xml ./conf/jetty-requestlog.xml32190 org.apache.catalina.startup.Bootstrap start
2爬橡、 jstack
jstack 主要用來查看某個Java進程內的線程堆棧信息治唤。語法格式如下:
jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip
pid: java應用程序的進程號,一般可以通過jps來獲得;
executable:產生core dump的java可執(zhí)行程序($JAVA_HOME/bin/java);
core:打印出的core文件;(jvm崩潰產生的core文件,從hs_err_pid log file 查看)
emote-hostname-or-ip:遠程debug服務器的名稱或IP
server-id: 唯一id,假如一臺主機上多個遠程debug服務;
option 說明如下:
-l糙申,會打印出額外的鎖信息宾添,在發(fā)生死鎖時可以用jstack -l pid來觀察鎖持有情況
-m 不僅會輸出Java堆棧信息,還會輸出C/C++堆棧信息(比如Native方法)
jstack -l pid
RUNNABLE,在虛擬機內執(zhí)行的郭宝。運行中狀態(tài)辞槐,可能里面還能看到locked字樣,表明它獲得了某把鎖粘室。
BLOCKED,受阻塞并等待監(jiān)視器鎖榄檬。被某個鎖(synchronizers)給block住了。
WATING,無限期等待另一個線程執(zhí)行特定操作衔统。等待某個condition或monitor發(fā)生鹿榜,一般停留在park(), wait(), sleep(),join() 等語句里。
TIMED_WATING,有時限的等待另一個線程的特定操作锦爵。和WAITING的區(qū)別是wait() 等語句加上了時間限制 wait(timeout)舱殿。
TERMINATED,已退出的。
查看耗時線程
top -Hp pid
printf "%x\n" 21226
獲取耗時線程id 的十六進制
52ec
獲取耗時信息
[root@2 logs]# jstack 21222 | grep 52ec
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fee24027000 nid=0x52ec runnable
3险掀、jmap(Memory Map)
jmap導出堆內存沪袭,然后使用jhat來進行分析
jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip
參數如下:
-heap:打印jvm heap的情況
-histo:打印jvm heap的直方圖。其輸出信息包括類名樟氢,對象數量冈绊,對象占用大小。-histo:live :同上埠啃,但是只打印存活對象的情況
-permstat:打印permanent generation heap情況(持久代)
輸出 類加載器名稱死宣、對象是否存活、對象地址碴开、父類加載器毅该、已加載的類大小等信息
-dump:<dump-options> 打印 dump(內存使用) 日志文件
jmap -heap pid
查看進程堆內存使用情況:****包括使用的GC算法、堆配置參數和各代中堆內存使用:
[root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -heap 32326
Attaching to process ID 32326, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 536870912 (512.0MB)
NewSize = 201326592 (192.0MB)
MaxNewSize = 201326592 (192.0MB)
OldSize = 335544320 (320.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 121634816 (116.0MB)
used = 105409240 (100.52608489990234MB)
free = 16225576 (15.473915100097656MB)
86.6604180171572% used
From Space:
capacity = 38797312 (37.0MB)
used = 6225208 (5.936820983886719MB)
free = 32572104 (31.06317901611328MB)
16.045462118612754% used
To Space:
capacity = 39845888 (38.0MB)
used = 0 (0.0MB)
free = 39845888 (38.0MB)
0.0% used
PS Old Generation
capacity = 335544320 (320.0MB)
used = 19401584 (18.502792358398438MB)
free = 316142736 (301.49720764160156MB)
5.782122611999512% used
19968 interned Strings occupying 2526840 bytes.
jmap -histo[:live] pid
查看堆內存中的對象數目潦牛、大小統(tǒng)計直方圖眶掌,如果帶上live則只統(tǒng)計活對象
[root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -histo 32326
num #instances #bytes class name
1: 351157 49044840 [C
2: 140145 26768472 [B
3: 30637 18927560 [I
4: 191987 4607688 java.lang.String
5: 46693 3523560 [Ljava.lang.Object;
6: 27813 2447544 java.lang.reflect.Method
7: 30591 2447048 [S
8: 58522 2340880 java.util.TreeMap$Entry
9: 81040 1683096 [Ljava.lang.Class;
10: 38542 1541680 java.util.HashMap$KeyIterator
11: 44546 1069104 java.lang.StringBuilder
12: 18696 1046976 java.util.concurrent.ConcurrentHashMap$KeyIterator
13: 37638 903312 java.util.Collections1
14: 10197 896216 [Ljava.util.HashMap$Node;
15: 7902 879416 java.lang.Class
class name是對象類型,說明如下:
B byte
C char
D double
F float
I int
J long
Z boolean
[ 數組巴碗,如[I表示int[]
[L+類名 其他對象
jmap -dump:format=b,file=dumpFileName pid
[root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -dump:format=b,file=/mnt/d.bat 32326
Dumping heap to /mnt/d.bat ...
Heap dump file created
問題:
這些工具真靠譜嗎朴爬?
大應用異常下 直接使用jmap jstack 根本無法加載內存信息或者耗時很久?
有什么可以替代嗎良价?
gcore寝殴?
二、MAT 分析Dump
Dump 是什么
Dump是反應Java堆使用情況的內存鏡像明垢,其中主要包括系統(tǒng)信息蚣常、虛擬機屬性、完整的線程Dump痊银、所有類和對象的狀態(tài)等抵蚊。 一般,在內存不足溯革、GC異常等情況下贞绳,我們就會懷疑有內存泄漏。這個時候我們就可以制作堆Dump來查看具體情況致稀。分析原因冈闭。
Dump 文件的分析有多種方式
1、命令jhat 分析(麻煩)
2抖单、**VisualVM** 工具分析 3萎攒、MAT 分析
MAT分析
J2SE中提供了一個簡單的命令行工具來對java程序的cpu和heap進行 profiling(剖析面),叫做HPROF
Shallow Size
對象自身占用的內存大小矛绘,不包括它引用的對象耍休。
針對非數組類型的對象,它的大小就是對象與它所有的成員變量大小的總和货矮。當然這里面還會包括一些java語言特性的數據存儲單元羊精。
針對數組類型的對象,它的大小是數組元素對象的大小總和囚玫。
Retained Size
Retained Size=當前對象大小+當前對象可直接或間接引用到的對象的大小總和喧锦。(間接引用的含義:A->B->C, C就是間接引用)
換句話說,Retained Size就是當前對象被GC后劫灶,從Heap上總共能釋放掉的內存裸违。
不過,釋放的時候還要排除被GC Roots直接或間接引用的對象本昏。他們暫時不會被被當做Garbage供汛。
**List objects --> with outgoing references **
:查看當前對象持有的外部對象引用(在對象關系圖中為從當前對象指向外的箭頭)
**List objects --> with incoming references **
:查看當前對象被哪些外部對象所引用(在對象關系圖中為指向當前對象的箭頭)
三、VM 實時監(jiān)控
四涌穆、遇到過OOM
1怔昨、剛開始用eclipse 開發(fā) ,沒事就本地OOM
2宿稀、DateForm oom
3趁舀、POI 導出xls 包含圖片
4、萬惡的死循環(huán)
5祝沸、hashmap
6矮烹、websocket 大內存長久占用
事故:
1越庇、遇到fullgc 了,oom了奉狈?完蛋
2卤唉、抓不出來dump ?完蛋
3仁期、jmap桑驱、jstack 都用不了?完蛋
1跛蛋、記錄時間點
2熬的、抓住一切日志可用日志(應用日志)
3、慢慢分析
參考
GC:https://www.cnblogs.com/wozixiaoyao/p/5658950.html
jstack:http://www.reibang.com/p/08b816d9b34f
executable core:https://lydawen.iteye.com/blog/2215300
內存劃分:https://www.cnblogs.com/haitaofeiyang/p/8392268.html
mat:http://www.cnblogs.com/trust-freedom/p/6744948.html#histogram