JVM系列——jvm常用指令,问题排查

JVM

  • 一、JVM常用指令
    • 1、jps(Java Process Status)
    • 2、jstat(Java Virtual Machine statistics monitoring tool)
      • (1)`jstat -gc pid 1000 10` 每隔1秒打印1次,共打印10次
      • (2)`jstat -gccapacity pid 1000 10`
      • (3)`jstat -gcutil pid 1000 10`
      • (4)`jstat -gccause pid 1000 10`
      • (5)`jstat -gcnew pid 1000 10`
      • (6)`jstat -gcold pid 1000 10`
      • (7)`jstat -gcpermcapacity pid 1000 10`
      • (8)使用jstat排查内存泄露
    • 3、jinfo(Java Virtual Machine Configuration Information)
      • (1)`jinfo -flag name pid` 查看指定的参数
      • (2)`jinfo -flag name=value pid` 修改指定名称的参数,不需要重启jvm虚拟机
      • (3)jinfo -flags pid 显示全部的配置参数
      • (4)jinfo -sysprops pid 以键值对的方式展示jvm虚拟机的全部属性
    • 4、jmap(JVM Meroy Map)
      • (1)jmap -heap pid 查看堆相关信息
      • (4)jmap -histo[:live] pid 显示堆中对象的统计信息
      • (3)`jmap -dump:live,format=b,file=filename.hprof pid` 生成dump文件
  • 二、排查案例
    • 1、 “线程出现死锁”、“内存占用居高不下”、“CPU占用居高不下”等问题,如何定位到具体的线程
    • 2、 “内存泄露”、“内存溢出”相关问题排查
      • `内存泄露`
      • `内存溢出`

一、JVM常用指令

1、jps(Java Process Status)

jps
   -l:输出进程的全类名,如果是jar包,则输出jar完整路径
   -m:输出虚拟机进程启动时传递给主类main()的参数
   -v:列出虚拟机进程启动时的jvm参数
   注意:如果某java进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令(以及jstat)将无法探知该进程

JVM系列——jvm常用指令,问题排查_第1张图片

2、jstat(Java Virtual Machine statistics monitoring tool)

jstat是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。在没有GUI图形界面时,它将是运行期定位虚拟机性能问题的首选工具,常用于检测垃圾回收问题以及内存泄漏问题。

(1)jstat -gc pid 1000 10 每隔1秒打印1次,共打印10次

JVM系列——jvm常用指令,问题排查_第2张图片各个参数含义:
新生代相关:
S0C:幸存区一的大小(字节)
S1C:幸存区二的大小(字节)
S0U:幸存区一已使用的大小(字节)
S1U:幸存区二已使用的大小(字节)
EC: Eden空间的大小(字节)
EU:Eden空间已使用的大小(字节)

老年代相关:
OC:老年代的大小(字节)
OU:老年代已使用的大小(字节)

方法区(元空间)相关:
MC:方法区的大小
MU:方法区已使用的大小
CCSC:压缩类空间的大小
CCSU:压缩类空间已使用的大小

其它
YGC:是指从启动到当前时刻young gc次数
YGCT:是指从启动到当前时刻young gc消耗的时间(秒)
FGC: 是指从启动到当前时刻full gc次数
FGCT:是指从启动到当前时刻full gc消耗的时间(秒)
GCT:是指从用启动到当前时刻gc消耗的总时间

(2)jstat -gccapacity pid 1000 10

显示与-gc基本相同,但输出关注Java各个区域使用到的最大,最小空间。

(3)jstat -gcutil pid 1000 10

显示内容与-gc基本相同,输出百分占比,例如:
JVM系列——jvm常用指令,问题排查_第3张图片

(4)jstat -gccause pid 1000 10

该命令会额外展示gc产生的原因
JVM系列——jvm常用指令,问题排查_第4张图片

(5)jstat -gcnew pid 1000 10

-gcnew:显示新生代gc状况
-gcnewcapacity:与上面基本相同,主要关注使用到的最大、最小空间

(6)jstat -gcold pid 1000 10

 -gcold:显示老年代gc状况
 -geoldcapacity:与gcold基本相同,注意关注使用到的最大、最小空间

(7)jstat -gcpermcapacity pid 1000 10

该命令显示永久代使用到的最大最小空间。

(8)使用jstat排查内存泄露

3、jinfo(Java Virtual Machine Configuration Information)

jinfo是jdk提供的一个可以实时查看和修改java虚拟机各种配置参数和系统属性的命令工具。使用jps -v可以查看Java虚拟机启动时显示指定的参数,查看没有显示指定的参数就可以使用jinfo指令进行查看。

(1)jinfo -flag name pid 查看指定的参数

jinfo -flag MaxHeapSize 123  --查看进程123的堆区的最大值

(2)jinfo -flag name=value pid 修改指定名称的参数,不需要重启jvm虚拟机

jinfo -flag MaxHeapSize=2g 123  --设置进程123的堆区最大为2g

(3)jinfo -flags pid 显示全部的配置参数

(4)jinfo -sysprops pid 以键值对的方式展示jvm虚拟机的全部属性

4、jmap(JVM Meroy Map)

jamp的作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标java进程的内存相关信息,包含java堆区各区域的使用情况,堆中对象的统计信息,类加载信息等

(1)jmap -heap pid 查看堆相关信息

JVM系列——jvm常用指令,问题排查_第5张图片

(4)jmap -histo[:live] pid 显示堆中对象的统计信息

JVM系列——jvm常用指令,问题排查_第6张图片

(3)jmap -dump:live,format=b,file=filename.hprof pid 生成dump文件

live:仅将存活的对象dump出
format:编码格式
flie:生成的文件名和路径

二、排查案例

1、 “线程出现死锁”、“内存占用居高不下”、“CPU占用居高不下”等问题,如何定位到具体的线程

  • 常见的出现“CPU居高不下”的原因:
    (1)属于计算密集型任务,大量计算会占用CPU
    (2) 程序进入了死循环
    (3)频繁gc,主要是gc线程占用着CPU

  • 排查步骤:
    (1)、使用top命令查看每个进程的运行情况,CPU,内存等指标;详见top命令详解
    (2)、在上一步观察到了某个进程运行异常后,可以使用top -H -p pid命令进行查看具体每个线程的运行情况
    JVM系列——jvm常用指令,问题排查_第7张图片
    (3)、使用jstack pid > a.txt 打印线程的堆栈信息
    在这里插入图片描述
    (4)、将第2步中运行异常的线程id转为16进制,比如上图的4807占用CPU最高,那这个时候可以使用printf "%x\n" pid,将线程id转换为16进制
    在这里插入图片描述
    (5)、到生成的文件中搜索转换出来的线程id,查看线程的堆栈信息
    JVM系列——jvm常用指令,问题排查_第8张图片

2、 “内存泄露”、“内存溢出”相关问题排查

内存泄露

内存泄露是指,申请的内存空间没有被使用,且长期没有被释放,导致一直占用着堆内存。值得注意的是这些没有被及时释放的内存一定是“可达的”,如果“不可达”就会被gc了。

内存溢出

内存溢出是指,在申请内存时,由于堆内存小于申请的内存,导致报错java.lang.OutOfMemoryError。

  • 常见的出现“内存泄露”的原因:
    (1)循环过多或者死循环,产生大量对象
    (2)静态集合引起的内存泄露,因为静态集合的生命周期和JVM一致,所以静态集合引用的对象不能被释放
    (3)连接建立过多,且未正常释放,比如socket连接,数据库连接等
    (4)内部类的对象被长期持有,那么内部类所属的外部类对象也不会被回收
    (5)HashMap中存入大量数据,当HashMap中的key的hash值发生改变,导致无法获取到原来的值,也无法删除
    (6)堆外内存泄露,类加载过多

  • 排查步骤:
    (1)使用jmap -heap pid,查看一下堆区的配置和使用情况,是否有异常
    (2)使用jmap -histo:[live] pid,查看对象的统计信息,可以找到占用内存异常的对象
    (3)使用jmap -dump:live,format=b,file=filename.hprof pid,导出堆内存快照
    (4)可以使用eclipse的MAT工具分析快照文件,然后找出占用内存异常的对象,可以通过查看对象之间的引用,定位到最终的代码

你可能感兴趣的:(JAVA,基础总结复习,jvm,java,linux,java虚拟机)