JVM常用监控工具和命令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiyongkang520/article/details/79354613

作为java开发,我们经常会使用一些java监控工具或者命令,来协助排查一些问题,例如内存泄露、某个进程突然cpu飙升、线程死锁、响应变慢等等问题。所以我们有必要了解和学会使用一些基本的监控工具和常用jdk命令。下面,笔者就简单介绍一下:

一、jvm常用命令

1、jps:jvm进程状况工具

jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
-q 不输出类名、Jar名和传入main方法的参数
- l 输出main类或Jar的全限名
-m 输出传入main方法的参数
- v 输出传入JVM的参数

例如:
这里写图片描述

2、jstat: jvm统计信息监控工具

jstat 是用于见识虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、jit编译等运行数据,它是线上定位jvm性能的首选工具。
命令格式:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

generalOption - 单个的常用的命令行选项,如-help, -options, 或 -version。

outputOptions -一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。
参数选项:
这里写图片描述
例如:查看gc 情况执行:jstat -gcutil 32448
这里写图片描述

3、jinfo: java配置信息

命令格式:
jinfo [option] pid
比如:获取一些当前进程的jvm运行和启动信息。
这里写图片描述

4、jmap: java 内存映射工具

jmap命令用于生产堆转存快照。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
命令格式:
jmap [ option ] pid

jmap [ option ] executable core

jmap [ option ] [server-id@]remote-hostname-or-IP

参数选项:
-dump:[live,]format=b,file= 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
-finalizerinfo 打印正等候回收的对象的信息.
-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
-permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
-h | -help 打印辅助信息
-J 传递参数给jmap启动的jvm.
例如:
使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况:
这里写图片描述

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图:
这里写图片描述

5、jhat:jvm堆快照分析工具

jhat 命令与jamp搭配使用,用来分析map生产的堆快存储快照。jhat内置了一个微型http/Html服务器,可以在浏览器找那个查看。不过建议尽量不用,既然有dumpt文件,可以从生产环境拉取下来,然后通过本地可视化工具来分析,这样既减轻了线上服务器压力,有可以分析的足够详尽(比如 MAT/jprofile/visualVm)等。

6、jstack:java堆栈跟踪工具

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
命令格式:
jstack [ option ] pid

jstack [ option ] executable core

jstack [ option ] [server-id@]remote-hostname-or-IP

参数:
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m打印java和native c/c++框架的所有栈信息.
-h | -help打印帮助信息
pid 需要被打印配置信息的java进程id,可以用jps查询.
例如:
这里写图片描述

二、可视化工具

对jvm监控的常见可视化工具,除了jdk本身提供的Jconsole和visualVm以外,还有第三方提供的jprofilter,perfino,Yourkit,Perf4j,JProbe,MAT等。这些工具都极大的丰富了我们定位以及优化jvm方式。
对于VisualVm来说,比较推荐使用,它除了对jvm的侵入性比较低以外,还是jdk团队自己开发的,相信以后功能会更加丰富和完善。jprofilter对于第三方监控工具,提供的功能和可视化最为完善,目前多数ide都支持其插件,对于上线前的调试以及性能调优可以配合使用。
另外对于线上dump的heap信息,应该尽量拉去到线下用于可视化工具来分析,这样分析更详细。如果对于一些紧急的问题,必须需要通过线上监控,可以采用 VisualVm的远程功能来进行,这需要使用tool.jar下的MAT功能。

1、jconsole

JConsole 是一个内置 Java 性能分析器,可以从命令行(直接输入jconsole)或在 GUI shell (jdk\bin下打开)中运行。

它用于对JVM中内存,线程和类等的监控。可使用JTop插件。它可以监控本地的jvm,也可以监控远程的jvm,也可以同时监控几个jvm。

这款工具的好处在于,占用系统资源少,而且结合Jstat,可以有效监控到java内存的变动情况,以及引起变动的原因。在项目追踪内存泄露问题时,很实用。
如下图:
这里写图片描述

2、visualvm

VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。本文主要介绍如何使用 VisualVM 进行性能分析及调优。
如下图:
这里写图片描述

三、常见问题排查

1、cpu飙升

在线上有时候某个时刻,可能会出现应用某个时刻突然cpu飙升的问题。对此我们应该熟悉一些指令,快速排查对应代码。

  1. 找到最耗CPU的进程
    指令:
    top
    这里写图片描述
  2. 找到该进程下最耗费cpu的线程
    指令:
    top -Hp pid
    这里写图片描述
  3. 转换进制
    echo ‘obase=16;172’|bc
    这里写图片描述
  4. 过滤指定线程,打印堆栈信息
    指令
    jstack pid |grep ‘threadPid’ -C5 –color

jstack 13525 |grep ‘0x3be4’ -C5 –color // 打印进程堆栈 并通过线程id,过滤得到线程堆栈信息。
threadPid注意都是小写,加上0x开头。
这里写图片描述

2、线程死锁

有时候部署场景会有线程死锁的问题发生,但又不常见。此时我们采用jstack查看下一下。比如说我们现在已经有一个线程死锁的程序,导致某些操作waiting中。

  1. 查找java进程id
    指令:
    top 或者 jps
    这里写图片描述
  2. 查看java进程的线程快照信息
    指令:
    jstack -l pid
    这里写图片描述

3、OOM内存泄露

java堆内的OOM异常是实际应用中常见的内存溢出异常。一般我们都是先通过内存映射分析工具(比如MAT)对dump出来的堆转存快照进行分析,确认内存中对象是否出现问题。
当然了出现OOM的原因有很多,并非是堆中申请资源不足一种情况。还有可能是申请太多资源没有释放,或者是频繁频繁申请,系统资源耗尽。针对这三种情况我需要一一排查。
OOM的三种情况:
1.申请资源(内存)过小,不够用。
2.申请资源太多,没有释放。
3.申请资源过多,资源耗尽。比如:线程过多,线程内存过大等。
排序顺序如下:

  1. 排查申请申请资源问题
    指令:jmap -heap 11869
    查看新生代,老生代堆内存的分配大小以及使用情况,看是否本身分配过小。
    这里写图片描述
  2. 排查gc
    特别是fgc情况下,各个分代内存情况。
    指令:jstat -gcutil 11938 1000 每秒输出一次gc的分代内存分配情况,以及gc时间

这里写图片描述
3. 查找最费内存的对象
指令: jmap -histo:live 11869 | more
这里写图片描述
上述输出信息中,最大内存对象才36M。如果某个对象占用空间很大,比如超过了100Mb,应该着重分析,为何没有释放。
注意,上述指令:
jmap -histo:live 11869 | more

执行之后,会造成jvm强制执行一次fgc,在线上不推荐使用,可以采取dump内存快照,线下采用可视化工具进行分析,更加详尽。

jmap -dump:format=b,file=/tmp/dump.dat 11869

或者采用线上运维工具,自动化处理,方便快速定位,遗失出错时间。
生成的二进制文件,可以使用eclipse或者其它ide的MAT(Memory Analyzer内存分析工具)插件打开查看,如下:
这里写图片描述
4. 确认资源是否耗尽
pstree 查看进程线程数量
netstat 查看网络连接数量
或者采用:
ll /proc/ P I D / f d | w c l / / l l / p r o c / {PID}/task | wc -l (效果等同pstree -p | wc -l) //打开的线程数

以上就是一些常见的jvm命令应用,笔者是学习公司架构人员整理的文档学习的,实战经验比较匮乏,希望给大家带来一定帮助!

猜你喜欢

转载自blog.csdn.net/qiyongkang520/article/details/79354613