使用top M 命令时查看java进程占用内存比例
使用top -Hp PID查看该进程下所有线程,以此可以查到占用CPU最大的线程
使用 jinfo PID 查看JVM信息
可以看到初始堆内存268M 最大堆内存520M 新生代89M 最大173M,老年代179M
查看一下垃圾回收情况,使用jstat -gc PID 1000 ,1秒打印一次
表头的意义:
本项目启动时间太短了,而且没用过多的连接使用,因此只能作为测试看看,实际调优前应当先压力测试。
默认E:S0:S1为8:1:1 ,默认新生代和老年代比例为1:2,
使用jmap -histo PID | head -10 查看堆中占用最大的前10个对象
使用 jmap -dump:live,format=b,file=/root/myheapdump.hprof PID 导出堆内存快照。
用visualVM进行离线分析。
服务器内存占用过高,直接卡死了,幸好已经导出来快照,明天再来
当晚在阿里云重启了一下服务器,花了一段时间
VisualVM的分析
服务器实际1.7G内存,其他占用百分之六十多,java占用25%,测试项目不大。
如果要调的话在tomcat bin/catalinna.sh里编辑
例如:
在# OS specific support。。。。下()写
JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"
以上测试的内存占用过高,如果是CPU占用过高的话:
用 top -Hp 查到CPU占用最高的线程
然后转换线程ID为16进制
printf "%x\n" 22542
之后定位cpu占用线程
jstack 22529 |grep 16进制线程id -A 20
[tomcat@localhost ~]$ jstack 22529 |grep 580e -A 20
"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f6d500c9000 nid=0x580e runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f6d500be000 nid=0x580d waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f6d50082000 nid=0x5808 in Object.wait() [0x00007f6d40ffe000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000806e0d58> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
频繁的GC也可能导致CPU负载过高
学习jstack:https://juejin.cn/post/6844904152850497543