zoukankan      html  css  js  c++  java
  • Java服务器内存过高&CPU过高问题排查

    一、内存过高

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

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

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

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

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

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

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

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

    ③一些特殊的标识的含义

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

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

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

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

    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:显示当前对象/线程引用的其他对象

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

     二、CPU过高(Windows系统)

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

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

    3、下载Process Explorer工具

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

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

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

    三、CPU过高(Linux系统)

    1、我们的Java服务器一般都是部署在Linux系统上面的,当出现CPU过高时,可以先用top命令找到CPU过高的Java进程的进程号

    2、然后进一步使用进程号来查看线程的情况

    top -H -p <PID>

    四、分析CPU问题

    1、上面我们找到了CPU过高的具体十进制线程号,使用科学计算器,将十进制的线程号转成十六进制,比如493620-->78834

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

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

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

    五、常用的分析工具

    1、查看Java进程中GC的情况,可以看到新生代老年代等的GC次数和GC时间等参数

    jstat -gc <PID>

    2、待补充

  • 相关阅读:
    实验四 数据库安全设计
    对订单数据库进行查询等操作
    vue学习笔记7 -组件之 父子组件之间的访问
    vue学习笔记6 父子组件的通信之 子组件修改由父组件传递过来的值 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed pro
    vue学习笔记5 组件
    vue学习笔记4 v-mode
    vue学习笔记3 购物车 实例
    vue学习笔记2 实例学习
    vue学习笔记1 《Vue.js 前端开发 快速入门与专业应用》
    postman学习:如何写断言
  • 原文地址:https://www.cnblogs.com/orange911/p/10414056.html
Copyright © 2011-2022 走看看