CPU过高排查
问题查询步骤 :
1> top : 查找到占用CPU最高的JAVA的PID
2> ps -mp 9491 -o THREAD,tid,time : 查找线程最占用CPU的线程TID
3> printf “%x\n” 9511 : 对线程TID进行转16进制 :
4> jstack 9491|grep 2527 -A 30 :
9491 : java进程
2527 : 转为十六进制的线程TID
可以看出是UserController.java:36最占用CPU
内存排查 : 内存泄漏 内存过高
1> jps 查询java程序 :
2> jmap -histo:live 10510|head -10 : 查询占用前十的class
3> 如果看的不清楚,可生成dump
导出整个JVM 中内存信息,可以利用其它工具打开dump文件分析,例如jdk自带的visualvm工具
jmap -dump:file=文件名.dump [pid]
4> 使用visualvm导入dump,进行分析
死锁排查 : 死锁代码参考下方
1> 使用jconsole -> 连接 -> 线程选项卡 -> 左下角检测死锁
2> ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
3> 使用命令
3.1> jps -l : jps查询java进程
3.2> jstack -l 10510 : 查询进程情况
在里面找waiting for(资源地址)和waiting to lock(资源地址)
相关命令 :
jps :
jps 命令类似与 linux 的 ps 命令,但是它只列出系统中所有的 Java 应用程序。
通过 jps 命令可以方便地查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息。
-q:只输出进程 ID
-m:输出传入 main 方法的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出jvm参数
-V:输出通过flag文件传递到JVM中的参数
jstack :
Stack Trace for Java,用于生成虚拟机当前的线程快照信息,包含每一条线程的堆栈信息。该命令通常用于定位线程停顿原因,当出现线程停顿时,可通过stack查看每个线程的堆栈信息,进而分析停顿原因。
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息
https://wangxinchun.iteye.com/blog/2315713
https://bijian1013.iteye.com/blog/2221340
jstat :
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。
https://www.cnblogs.com/lizhonghua34/p/7307139.html
jstat -class pid : 类加载统计
jstat -compiler pid : 编译统计
jstat -gc pid1000 : 每隔1秒打印一次垃圾回收统计
jstat -gccapacity pid : 堆内存统计
jstat -gcnew pid : 新生代垃圾回收统计
jstat -gcnewcapacity pid : 新生代内存统计
jstat -gcold pid : 老年代垃圾回收统计
jstat -gcoldcapacity pid : 老年代内存统计
jstat -gcmetacapacity pid : 元数据空间统计
jstat -gcutil pid : 总结垃圾回收统计
jstat -printcompilation pid : JVM编译方法统计
- fullgc频繁说明old区很快满了
- 如果是一次fullgc后,剩余对象不多,那么说明你eden区设置太小,导致段生命周期的对象进入了old区.
- 如果一次fullgc后,old区回收率不大,那么说明old区太小.
jmap :
jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
https://www.jianshu.com/p/a4ad53179df3
jinfo :
jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息
https://www.jianshu.com/p/8d8aef212b25
jvm监控工具 :
- jconsole.exe [jdk/bin/目录]
- jvisualvm.exe [jdk/bin/目录]
- jprofile
ThreadMXBean : https://www.cnblogs.com/wzhanke/p/4460891.html
ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
ThreadInfo[] dumpAllThreads = tmx.dumpAllThreads(false, false);
for (ThreadInfo threadInfo : dumpAllThreads) {
System.err.println(threadInfo);
}
// 获取死锁线程
long[] ids = tmx.findDeadlockedThreads();
if (ids != null) {
ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
System.out.println("The following threads are deadlocked:");
for (ThreadInfo ti : infos) {
System.out.println(ti);
}
}
模拟死锁 :
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class DeadLockTesting {
public static void startLock(){
Object obj1 = new Object();
Object obj2 = new Object();
DeadLockThread t1 = new DeadLockThread(obj1, obj2);
DeadLockThread t2 = new DeadLockThread(obj2, obj1);
t1.start();
t2.start();
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
MonitorThread mt = new MonitorThread();
mt.start();
}
}
class MonitorThread extends Thread {
public void run() {
ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
long[] ids = tmx.findDeadlockedThreads();
if (ids != null) {
ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
System.err.println("The following threads are deadlocked:");
for (ThreadInfo ti : infos) {
System.out.println(ti);
}
}
}
}
class DeadLockThread extends Thread {
private Object obj1;
private Object obj2;
public DeadLockThread(Object obj1, Object obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}
public void run() {
synchronized (obj1) {
try {
Thread.sleep(1000);
synchronized (obj2) {
System.err.println("=============");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}