Java服务器内存过高&CPU过高问题排查

商务办公
当程序发现CPU过高的情况时,可以使用Windows系统的Process Explorer工具来找到CPU高消耗的线程,所以需要在Windows机器上面搭建好服务器的测试环境,尽量模拟出线上CPU飙升的情况。

[[264098]]

 一、内存过高

1、内存过高一般有两种情况:内存溢出和内存泄漏

(1)内存溢出:程序分配的内存超出物理机的内存大小,导致无法继续分配内存,出现OOM报错

(2)内存泄漏:不再使用的对象一直占据着内存不释放,导致这块内存浪费掉,久而久之,内存泄漏的对象堆积起来,也会导致物理机的内存被耗尽,出现OOM报错

2、内存过高的检测办法:通常我们的Java服务器部署在Linux机器上面,可以通过jvm自带的命令进行一些检测

(1)查看对象的数目和占用内存大小

①参数为Java程序的进程号,将结果导出到指定目录中,

  1. jmap -histo:live <进程号> > <导出目录+文件名> 

②示例如下,可以看到程序中各个对象所占用内存的情况,根据占用字节数大小降序显示,这里只能看出哪些对象占用内存高,但是还不能具体定位到问题代码,需要进一步排查

③一些特殊的标识的含义

  • [C 表示char[],一般与String对象相关,因为String其实就是基于char数组实现的
  • [S 表示short[]
  • [I 表示int[]
  • [B 表示byte[]
  • [II 表示int[][]
    1. num #instances #bytes class name 
    2. ---------------------------------------------- 
    3.  1: 585152 75635896 [C 
    4.  2: 66541 71446496 [B 
    5.  3: 1141734 36535488 java.util.HashMap$Entry 
    6.  4: 176622 26086840 <constMethodKlass> 
    7.  5: 176622 24034208 <methodKlass> 
    8.  6: 17717 19584560 <constantPoolKlass> 
    9.  7: 174454 18375128 [Ljava.util.HashMap$Entry; 
    10.  8: 571222 13709328 java.lang.String 
    11.  9: 832783 13324528 java.lang.Integer 
    12.  10: 17717 13198840 <instanceKlassKlass> 
    13.  11: 15092 11237440 <constantPoolCacheKlass> 
    14.  12: 46779 10429728 [I 
    15.  13: 191501 7660040 java.util.LinkedHashMap$Entry 
    16.  14: 12599 6567592 <methodDataKlass> 
    17.  15: 113526 6357456 java.util.HashMap 
    18.  16: 197998 6335936 java.util.Hashtable$Entry 

(2)如果需要进一步定位问题代码,那么就需要把Java程序的内存镜像导出,再具体分析了,通过如下命令导出程序的内存镜像

  1. jmap -dump:format=b,file=<导出目录+文件名> <进程号> 

(3)下载Memory Analyzer工具来分析内存镜像

  1. http://www.eclipse.org/mat/ 

(4)打开软件后,File-->Open Heap Dump...,打开刚才导出的镜像文件,选择Leak Suspects Report,Finish,进入分析页面

  • Histogram:列表展示出内存中的对象数目和占用内存大小
  • Dominator Tree:列表展示出程序中每个线程中的对象数目和占用内存大小
  • Top Consumers:图表展示出每个线程的对象数目和占用内存大小
  • Top Components:图表展示出内存中的对象数目和占用内存大小
  • Leak Suspects:这个是最常用的,会自动检测分析内存异常的原因

右键对象-->show objects by class可以查看对象的具体情况

by incomming reference:显示引用该对象/线程的其他对象

by outgoing reference:显示当前对象/线程引用的其他对象

 

Java服务器内存过高&CPU过高问题排查

 

(5)点击Leak Suspects,程序会分析出可能存在内存问题的地方,继续点击Detail可以看到具体有哪些对象和线程,接下来就要根据具体情况具体分析了

二、CPU过高

1、当程序发现CPU过高的情况时,可以使用Windows系统的Process Explorer工具来找到CPU高消耗的线程,所以需要在Windows机器上面搭建好服务器的测试环境,尽量模拟出线上CPU飙升的情况

2、模拟好环境后,通过任务管理器,在进程一栏中找到Java程序的进程号

 

Java服务器内存过高&CPU过高问题排查

 

3、下载Process Explorer工具

  1. https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer 

4、打开工具后,根据刚才的进程号找到进程

 

Java服务器内存过高&CPU过高问题排查

 

5、然后右键-->Properties,再选择Threads选项卡,点进CPU排序,可以找到消耗CPU最多的那个线程

 

Java服务器内存过高&CPU过高问题排查

 

6、使用科学计算器,将十进制的线程号转成十六进制,比如493620-->78834

 

Java服务器内存过高&CPU过高问题排查

 

7、到此已经拿到了可能出问题的进程号和线程号,接下来使用jvm内置的命令来导出Java的堆栈信息

  1. jstack -l <进程号> > <导出目录+文件名> 

8、打开导出的堆栈信息,并全文搜索刚刚拿到的十六进制的线程号,就可以找到出问题的代码具体位置了

作者:未分配的为服务

责任编辑:武晓燕 来源: 今日头条
相关推荐

2020-11-02 09:25:33

CPUJava线程

2010-08-18 09:52:25

Memcache

2020-11-06 00:45:29

Linux服务器swap内存

2018-11-26 08:49:42

CPU排查负载

2024-03-19 09:15:12

服务器CPUI/O

2018-08-10 15:00:42

服务器内存排查

2013-10-30 17:34:51

Nginx服务器软中断XEN虚拟

2019-07-24 11:52:11

CPU服务器面试官

2018-08-17 08:44:37

服务器内存排查

2023-03-05 16:40:07

linux进程内存

2022-06-27 11:20:13

工具内存GO

2023-09-22 07:46:22

CPU温度笔记本

2022-03-11 07:30:04

SQLMySQLCPU

2021-06-02 09:55:20

JVM排查JVM内存过高技术

2021-05-12 06:57:03

Windows 10Windows操作系统

2022-08-04 13:58:28

Windows 11微软CPU

2017-02-16 19:39:29

Windows 10System进程CPU

2021-08-12 10:49:19

Spring Clou内存Java

2012-11-30 09:50:37

亚马逊云服务

2020-12-20 10:37:06

Windows10操作系统CPU
点赞
收藏

51CTO技术栈公众号