一、定位异常进程
查找cpu、内存占用较高的进程
1、打印进程的线程指标,找出cpu占用较高的进程:
ps -H -eo pid,tid,%cpu
2、过滤其他进程的线程:
ps -H -eo pid,tid,%cpu | grep [pid]
3、列出进程中所有的线程信息(jstack的线程编号是16进制的,需要转成十进制)
(1)查询所有java进程id
jps -l
(2)列出java进程中所有的线程信息
jstack pid
4、查看堆内存内存使用情况
(1) jmap查看内存分布
jmap -heap [pid] (jdk8)
jhsdb jmap --heap --pid [pid] (jdk17)
(2) jmap生成内存快照文件
jmap -dump:live,format=b,file=mydump.hprof [pid]
(3) jinfo查看java进程中jvm参数
jinfo -flags pid
(4)jstat查看内存统计
参数说明:
Options — 选项,我们一般使用 -gcutil 查看gc情况
vmid — VM的进程号,即当前运行的java进程号
interval – 间隔时间,单位为秒或者毫秒
count — 打印次数,如果缺省则打印无数次
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
例子:30秒采集一次堆内存容量、垃圾回收情况
jstat -gcutil pid 30000
二、JVM调优参数
如新生代内存设置过小,在并发情况下,大量请求进入,大量新对象创建,造成新生代内存紧张,不得不将创建得对象晋升至老年代,不断有新的对象进入老年代,造成老年代内存紧张,引起fullgc。
1、垃圾回收器分类
2、设置垃圾回收器参数
(1)查看默认垃圾回收器:
-XX:+PrintCommandLineFlags -version
(2)设置打印GC信息:
-XX:+PrintGCDetails
(3)设置G1 GC
-XX:+UseG1GC
(4)年轻代初始化占整个Java Heap的大小(默认值为5%)
-XX:G1NewSizePercent
(5)年轻代最大占整个Java Heap的大小(默认值为60%)
-XX:G1MaxNewSizePercent
(6)设置jvm参数:
-Xms1024m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
-Xms(初始堆内存)
-Xmx(最大堆内存)
-Xmn(新生代内存)
-XX:PermSize=永久区初始大小
-XX:MaxPermSize= 永久区最大值
-XX:NewRatio (新生代老年代比例,-XX:NewRatio=3(新:老=1:3),新生代占堆的1/4)
-XX:SurvivorRatio (-XX:SurvivorRatio=8,一个幸存区Survivor和伊甸区的比例,即幸存区占新生代的1/10)
-Xss 虚拟机栈大小
-XX:+HeapDumpOnOutOfMemoryError 开启生成溢出内存快照文件
-XX:HeapDumpPath=/xxxx 指定内存快照文件生成的路径
3、java应用启动参数设置
(1)堆内存大小配置
JAVA_OPTS="${JAVA_OPTS} -server -Xms1024m -Xmx1024m -Xmn256m -XX:SurvivorRatio=8"
JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump"
(2)jconosle远程连接配置
tomcat设置
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.81.200 -
Dcom.sun.management.jmxremote.port=9016 -Dcom.sun.management.jmxremote.rmi.port=9016 -
Dcom.sun.management.jmxremote.ssl=false -
Dcom.sun.management.jmxremote.authenticate=false"
springboot项目配置:
java
-Djava.rmi.server.hostname=192.168.81.200
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-jar app.jar
三、内存溢出分析
使用eclipse的MAT(Eclipse Memory Analyzer )工具导入内存快照,通过工具图形化可以很清晰的看出大对象
1、定位大对象
dominator_tree查看大对象引用关系,thread_overview定位大对象产生的线程方法栈
2、OQL语句
OQL语句也是分析对象情况的一个重要利器:
SELECT * FROM java.lang.String
SELECT toString(s), s.count, s.value FROM java.lang.String s
SELECT toString(s) AS "字符串", @usedHeapSize AS "占用内存大小" FROM java.lang.String s
SELECT * FROM java.lang.String s WHERE toString(s)="idea"
SELECT * FROM java.lang.String s WHERE toString(s) lIKE "mysql://*"
SELECT * FROM java.lang.String s WHERE toString(s)="idea" AND s.@usedHeapSize>100
3、mat启动指定jdk版本
进入configuration打开config.ini查看需要的jdk版本
这里可以看到需要jdk1.8,那么可以通过两种方式指定jdk环境
(1)命令行方式:
MemoryAnalyzer.exe -vm D:\software\jdk\jdk8\bin
(2)配置文件:
在 MemoryAnalyzer.ini文件中配置