linux下jvm问题排查

1,348 阅读2分钟

linux下jvm问题排查

前言

最近几天,运维告诉我刚上线的java服务占用内存过高。

下面讲述排查问题的具体过程

问题排查步骤

  1. 进程ID: ​ jps [ options ][ hostid ] ​ 使用jps:jps -l ​ 使用ps:ps aux | grep tomat ​ 虚拟机统计信息监视工具:jstat: ​ jstat [ option vmid [interval[s|ms][count]] ] ​ jstat -gcutil pid 1000 意思是每1000毫秒查询一次,一直查。gcutil的意思是已使用空间站总空间的百分比

  2. Java内存影像工具:jmap: ​ jmap [ option ] vmid ​ jmap -histo:live pid ​ jmap -histo:live pid | head -7

  3. 生成离线文件

    $ jmap -dump:live,format=b,file=pid.hprof pid
    
  4. MAT分析工具

  5. 启动项目时加入-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/java/dump 分析内存溢出时的具体内容

排查问题

  1. 通过top命令找到占用内存最多的进程

    $ top 
    

  2. 通过top -Hp pid查看线程的详细情况,例如上面 3231进程

    $ top -Hp 3231
    

    我们就分析红线标注的线程

  3. 通过jstack pid >> pid.txt命令,将线程栈输出到txt文件,例如3231进程

    $ jstack 3231 >> 3231.txt
    

    输出到3231.txt文件

    -rw-rw-r-- 1 work work   48292 Oct 30 17:35 3231.txt
    
  4. 我们以第2步的红线标注线程为例

    3239转换为16进制,转换命令为printf "%x\n" pid

    $ printf "%x\n" 3239
    

    输出

    ca7
    
  5. 3231.txt文件中寻找线程为ca7的信息

    $ cat 3231.txt | grep ca7
    

    输出

    "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f627c13b000 nid=0xca7 waiting on condition [0x0000000000000000]
    

    也可以使用grep -C或者vim 3231.txt文件查看

  6. 通过具体线程的信息即可分析问题的关键所在

内存分析常用工具(扩展)

  1. jmap:用来查看堆内存使用状况,一般结合jhat使用

  2. jstack:主要用来查看某个Java进程内的线程堆栈信息

    语法

    jstack [option] pid
    
  3. jstat:主要用来查看某个Java进程内的线程堆栈信息

    我常用的命令是jstat -gcutil pid interval,例如

    $ jstat -gcutil 3231 1000
    

    每10秒刷新一次jvmgc信息

  4. jps :主要用来输出JVM中运行的进程状态信息

    OPTION

    -q: 不输出类名、Jar名和传入main方法的参数 - m:输出传入main方法的参数 -l:输出main类或Jar的全限名 -v:输出传入JVM的参数

总结

本文主要讲述的是对占用内存或者cpu过高的进程进行分析并找到问题所在的思路。