当前位置: 首页 > 科技观察

Java高CPU高内存问题排查

时间:2023-03-12 17:59:07 科技观察

下面通过一个模拟实例来分析排查Java应用高CPU高内存的过程。如果是Java面试,这两个问题在面试的时候出现的概率很高,所以我打算在这里总结一下。1、排查JavaCPU高问题如下:packagecom.classloading;publicclassTest{staticclassMyThreadextendsThread{publicvoidrun(){//无限循环,消耗CPUinti=0;while(true){i++;}}}publicstaticvoidmain(Stringargs[])throwsInterruptedException{newMyThread().start();Thread.sleep(10000000);}}使用top命令查看占用CPU过多的进程。如下所示。查看进程6102下线程的占用情况,如下图。使用如下命令将6122转换为16进制表示,如下:导出CPU占用率高的进程的线程栈。命令如下:jstackpid>>java.txt内容如下:mazhi@mazhi:~$catjava.txtAttachingtoremoteserverpid,pleasewait...2021-02-2315:38:18FullthreaddumpJavaHotSpot(TM)64-BitServerVM(25.192-b12mixedMode):“contactListener”#10DAEMONPRIO=9OS_PRIO=0TID=0x00007F4EE0001000NID=0x1956Runnable[0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000大号]=0tid=0x00007f4f180d6000nid=0x17earunnable[0x00007f4f044da000]java.lang.Thread.State:RUNNABLEatcom.cpuhigh.Test$MyThread.run(Test.java:8)//这里表示第8行,是死循环代码的开始。..exportedstackinformation线程的状态(一般是找RUNNABLE状态)和调用栈结合起来找问题。Threaddump分析:threaddump分析的主要目的是定位线程长时间停顿的原因2.排查Java内存过大问题例如:packagecom.classloading;importjava.util.ArrayList;importjava.util.List;publicclassTest{privatestaticfinalintUNIT_MB=1024*1024;publicstaticvoidmain(Stringargs[])throwsInterruptedException{Listx=newArrayList();inti=0;while(i<1000){x.add(newbyte[UNIT_MB]);i++;}Thread.sleep(1000000000);}}通过jmap转储的内存快照。如果是在线环境,转储前注意断流,否则大内存转储会直接卡死服务。命令行输入:jmap-histo|head-20,可以查看某个pid的java服务占用内存的前20个类,如下图。可以看出,字节数组占用的内存最多,一共有1008个实例。jmap还有一条将整个内存转成文件保存的指令,如下:jmap-dump:format=b,file=filename.bin执行指令如下图。它可以在JVM启动时设置。如果发生OOM,文件将被转储。命令如下:-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/tmp/heapdump.hprof如果快照文件不大,可以下载到本地,然后用MAT或者在线分析(https://fastthread.io/);如果快照文件很大,可以直接在服务器上分析。使用的命令是:jhatdump.hprofjhat也是jdk自带的工具之一。主要用来分析java堆的命令。可以以html的形式显示堆中的对象,包括对象的个数、大小等,支持对象查询语言。命令执行后如下图所示。访问如下图所示。Showheaphistogram将显示对象占用的固有大小。如下所示。