JVM - 线上节点死机应该怎么处理?linux线上问题排查,jvm命令查找

监控工具:arthas

开启dump日志

-XX:+HeapDumpOnOutOfMemoryError 默认关闭,建议开启,在java.lang.OutOfMemoryError 异常出现时,输出一个dump.core文件,记录当时的堆内存快照。
-XX:HeapDumpPath=./java_pid.hprof 用来设置堆内存快照的存储文件路径,默认是java进程启动位置。

进行对dump日志进行分析,判断是哪里出现了OOM。
在这里插入图片描述

Java heap space错误产生的常见几类

  1. 请求创建一个超大对象,通常是一个大数组。
  2. 超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
  3. 过度使用总结器(Finalizer),该对象没有立即被GC
  4. 内存泄露(Memory Leak),大量对象引用没有释放,JVM无法对其自动回收,常见于使用了File等资源没有回收。

解决方案

针对大部分情况,通常只需要通过 -Xmx参数调高JVM堆内存空间即可。如果仍然没有解决参考进一步处理:

  1. 如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全结果,而没有做结果数限制
  2. 如果是业务峰值压力,可以考虑添加机器资源,或者做限制降级。
  3. 如果是内存泄露,需要找到持有的对象,修改代码设计,比如关闭没有释放的链接。

jstack找出占用cpu最高的线程堆栈信息

package com.mahan.jvm;
/** 
* 运行此代码,cpu会飙高 
*/ 
public class Math { 
	public static final int initData = 666; 
	public static User user = new User(); 
	
	public int compute() { //一个方法对应一块栈帧内存区域 
		int a = 1; 
		int b = 2; 
		int c = (a + b) * 10; 
		return c; 
	} 
	
	public static void main(String[] args) { 
		Math math = new Math(); 
		while (true){ 
			math.compute();
		}
	}
}
  1. 出应用进程的PID
ps -ef|grep java

[root@zabbix-agent bin]# jps -l
1217 sun.tools.jps.Jps
1094 org.apache.catalina.startup.Bootstrap

[root@zabbix-agent bin]# ps -ef|grep java
root       1094      1  0 18:35 pts/0    00:00:17 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/bin/java -Djava.util.logging.config.file=/home/apache-tomcat-8.5.31/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/apache-tomcat-8.5.31/bin/bootstrap.jar:/home/apache-tomcat-8.5.31/bin/tomcat-juli.jar -Dcatalina.base=/home/apache-tomcat-8.5.31 -Dcatalina.home=/home/apache-tomcat-8.5.31 -Djava.io.tmpdir=/home/apache-tomcat-8.5.31/temp org.apache.catalina.startup.Bootstrap start

或top命令查询CPU使用率PID,然后执行 top -p , 按H,获取每个线程的内存情况
在这里插入图片描述

  1. 找到应用进程的PID为1094,接着找出该进程最消耗CPU的线程,可以使用ps -Lfp 1094 或者top -Hp 1094来查看该进程中线程的cpu消耗情况
[root@zabbix-agent bin]# top -Hp 1094
top - 19:40:51 up  1:52,  1 user,  load average: 0.00, 0.01, 0.05
Threads:  44 total,   0 running,  44 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   998628 total,    84224 free,   690548 used,   223856 buff/cache
KiB Swap:  2097148 total,  2068536 free,    28612 used.   146256 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                         
  1094 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1095 root      20   0 2778656  84996   5324 S  0.0  8.5   0:01.01 java                                            
  1096 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.54 java                                            
  1097 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1098 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1099 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1100 root      20   0 2778656  84996   5324 S  0.0  8.5   0:03.06 java                                            
  1101 root      20   0 2778656  84996   5324 S  0.0  8.5   0:01.46 java                                            
  1102 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1103 root      20   0 2778656  84996   5324 S  0.0  8.5   0:06.76 java                                            
  1104 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.59 java
  1. 查看到线程1103的消耗CPU时间是最大的,用命令查看线程的十六进制值
[root@zabbix-agent bin]# printf "%x\n" 1103
44f
  1. 查询到的值44f 用于下面jstack 定位信息。执行 jstack 1094|grep -A 10 44f,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调 用方法
[root@zabbix-agent bin]# jstack 1094|grep 44f
"VM Periodic Task Thread" os_prio=0 tid=0x00007f602c01bc80 nid=0x44f waiting on condition

在这里插入图片描述

这样就可以看到VM Periodic Task Thread 是最耗时的类,然后就可以去代码审查代码了。

docker中没有jvm相关命令?

从宿主机,将jps、jstack、jmap等拷入docker容器中jre的bin目录下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值