1甜橱、內(nèi)存Heap Dump文件抓取
heap dump記錄了JVM中堆內(nèi)存運行的情況桐早。
- XX:+HeapDumpOnOutOfMemoryError
? 應(yīng)用啟動時配置參數(shù)癣缅,當OutOfMemoryError發(fā)生時自動生成 Heap Dump 文件。這可是一個非常有用的參數(shù)哄酝,因為當你需要分析Java內(nèi)存使用情況時所灸,往往是在OOM(OutOfMemoryError)發(fā)生時。-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=data
注意:JVM 生成 Heap Dump 的時候炫七,虛擬機是暫停一切服務(wù)的爬立。如果是線上系統(tǒng)執(zhí)行 Heap Dump 時需要注意。
2万哪、線程Thread Dump文件抓取
Thread dump 文件記錄了當時JVM中線程運行的情況侠驯,Thread dumps 能幫助我們判斷 CPU 峰值、死鎖奕巍、內(nèi)存異常吟策、應(yīng)用反應(yīng)遲鈍、響應(yīng)時間變長和其他系統(tǒng)問題的止。
- kill -3
出于安全方面的考慮檩坚,生產(chǎn)環(huán)境有時候只包含JRE環(huán)境,這時jdk下的工具就不能用了kill -3 <pid> kill -3 37320
3、GUI分析工具——JVisualVM/JConsole
JConsole :
JDK提供的一個基于GUI查看JVM系統(tǒng)信息的工具匾委,既可以管理本地的JVM拖叙,也可以管理遠程的JVMJVisualVM:
JDK提供的可以從本地或者遠程運行的 JVM 里抓取 dump 文件。
https://www.cnblogs.com/xifengxiaoma/p/9402497.html
https://blog.csdn.net/moneyshi/article/details/81511687
JVisualVM/JConsole雖然用起來很方便赂乐,但是如果要連接遠程機器上的jvm薯鳍,則遠程機器上的jvm需要加參數(shù)(本地的不需要),所以生產(chǎn)環(huán)境上我們通常是不會直接用這兩個工具的挨措,這時就需要用到命令行工具了挖滤。
4、命令行工具
4.1 jmap
Jmap是一個JDK提供的可以輸出所有內(nèi)存中對象的工具浅役,甚至可以將VM 中的heap斩松,以二進制輸出成文本。打印出某個java進程(使用pid)內(nèi)存內(nèi)的觉既,所有‘對象’的情況(如:產(chǎn)生那些對象砸民,及其數(shù)量)。
常用命令
jmap -heap pid
查看進程堆內(nèi)存詳細信息奋救,包括使用的GC算法、堆配置參數(shù)和各代中堆內(nèi)存使用情況jmap -histo[:live] pid
查看java堆中對象的相關(guān)信息反惕,包含數(shù)量以及占用的空間大小尝艘,如果帶上live則只統(tǒng)計活對象jmap -permstat pid
打印進程的類加載器和類加載器加載的持久代對象信息,輸出:類加載器名稱姿染、對象是否存活(不可靠)背亥、對象地址、父類加載器悬赏、已加載的類大小等信息
- jmap -dump:live,format=b,file=heap-dump.bin <pid>
生成Heap Dump到文件狡汉,其中的pid是JVM進程的id,heap-dump.bin是生成的文件名稱闽颇,在執(zhí)行命令的目錄下面盾戴,可以把生成的dump文件加載到GUI工具中查看
4.2 jstack——jdk包含
jstack主要用來查看某個Java進程內(nèi)的線程堆棧信息,jstack可以定位到線程堆棧兵多,根據(jù)堆棧信息我們可以定位到具體代碼尖啡,所以它在JVM性能調(diào)優(yōu)中使用得非常多
jstack -F pid
檢查是否有死鎖jstack -l pid
打印出額外的鎖信息,在發(fā)生死鎖時可以用jstack -l pid來觀察鎖持有情況jstack -l 37320 > /opt/tmp/threadDump.txt
保存 dump 信息到文件使用實例:系統(tǒng)cpu消耗比較高剩膘,那我們怎么定位到是哪里出問題衅斩?
- 先找出java進程ID;
ps -ef | grep flybird —— 21711 - 找出該進程內(nèi)最耗費CPU的線程怠褐;
top -Hp pid ——21742 - 輸出進程21711的堆棧信息畏梆,并且查詢到具體的線程id;
jstack 21711 | grep 54ee
注意:54ee是線程id 21742的16進制值
4.3 jstat(JVM統(tǒng)計監(jiān)測工具)
jstat -gc 91328
查看jvm垃圾回收情況,包括FGC奠涌、YGC的總次數(shù)和累計耗時jstat -gcutil 91328
功能和gc 一樣宪巨,但是是百分比的形式,讀取更友好jstat -gccapacity 91328
讀取各個代區(qū)的當前容量铣猩、最大容量揖铜、當前使用量等信息
5、調(diào)優(yōu)
- -Xms:設(shè)置初始分配大小达皿,默認為物理內(nèi)存的“1/64”天吓;
- -Xmx:最大分配內(nèi)存,默認為物理內(nèi)存的“1/4”峦椰;
- -Xss規(guī)定了每個線程堆棧的大小躬存。一般情況下256K是足夠了度硝。太大了影響此進程中并發(fā)線程數(shù)大小;
在整個堆內(nèi)存的調(diào)整策略之中霞掺,有經(jīng)驗的人基本只會調(diào)整兩個參數(shù):“-Xmx”(最大內(nèi)存)、“-Xms”(初始化內(nèi)存)圈澈。如果要取得這些內(nèi)存的整體信息痘昌,直接利用Runtime類即可;
在很多情況下餐茵,-Xms和-Xmx設(shè)置成一樣的科阎。這么設(shè)置,是因為當Heap不夠用時忿族,會發(fā)生內(nèi)存抖動锣笨,影響程序運行穩(wěn)定性。
通過 ps -ef | grep java 可以查詢到啟動時設(shè)置的這些參數(shù)道批,如下
$ ps -ef | grep java
user_00 1689 1 1 Oct19 ? 17:39:05 /usr/local/services/elasticsearch-7.2.1/jdk/bin/java
-Xms2g
-Xmx2g
-Xss1m
-XX:+UseG1GC
-XX:MaxTenuringThreshold=15
-XX:MaxGCPauseMillis=3000
-XX:InitiatingHeapOccupancyPercent=75
-Des.networkaddress.cache.ttl=60
-Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch
-Djava.awt.headless=true
-Dfile.encoding=UTF-8
-Djna.nosys=true
-XX:-OmitStackTraceInFastThrow
-Dio.netty.noUnsafe=true
-Dio.netty.noKeySetOptimization=true
-Dio.netty.recycler.maxCapacityPerThread=0
-Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true
-Djava.io.tmpdir=/tmp/elasticsearch-2105800618487179719
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=data
-XX:ErrorFile=logs/hs_err_pid%p.log
-Xlog:gc*,gc+age=trace,
safepoint:file=/data/elasticsearch/logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m
-Djava.locale.providers=COMPAT -Dio.netty.allocator.type=pooled
-XX:MaxDirectMemorySize=1073741824
-Des.path.home=/usr/local/services/elasticsearch-7.2.1
-Des.path.conf=/usr/local/services/elasticsearch-7.2.1/config
-Des.distribution.flavor=default -Des.distribution.type=tar
-Des.bundled_jdk=true -cp /usr/local/services/elasticsearch-7.2.1/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /usr/local/services/elasticsearch-7.2.1/logs/elasticsearch.pid --quiet