# Table of Contents
* 一、jvm常见监控工具&指令
* 1、 jps:jvm进程状况工具
* 2、jstat: jvm统计信息监控工具
* 3、jinfo: java配置信息
* 4、jmap: java 内存映射工具
* 5、jhat:jvm堆快照分析工具
* 6、jstack:java堆栈跟踪工具
* 二、可视化工具
* 三、应用
* 1、cpu飙升
* 2、线程死锁
* 2.查看java进程的线程快照信息
* 3、OOM内存泄露
* 参考文章

| |

|

| |

| 。 | |

| |

| 在常见的线上问题时候,我们多数会遇到以下问题: |

| |

| > * 内存泄露 |

| > * 某个进程突然cpu飙升 |

| > * 线程死锁 |

| > * 响应变慢...等等其他问题。 |

| |

| 如果遇到了以上这种问题,在线下可以有各种本地工具支持查看,但到线上了,就没有这么多的本地调试工具支持,我们该如何基于监控工具来进行定位问题? |

| |

| 我们一般会基于数据收集来定位,而数据的收集离不开监控工具的处理,比如:运行日志、异常堆栈、GC日志、线程快照、堆快照等。经常使用恰当的分析和监控工具可以加快我们的分析数据、定位解决问题的速度。以下我们将会详细介绍。 |

| |

| ## 一、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等选项配合使用。复制代码 | | |

| |

| 参数选项: |

| |

| | Option | Displays | Ex | |

| | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | |

| | class | 用于查看类加载情况的统计 | jstat -class pid:显示加载class的数量,及所占空间等信息。 | |

| | compiler | 查看HotSpot中即时编译器编译情况的统计 | jstat -compiler pid:显示VM实时编译的数量等信息。 | |

| | gc | 查看JVM中堆的垃圾收集情况的统计 | jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。 | |

| | gccapacity | 查看新生代、老生代及持久代的存储容量情况 | jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小 | |

| | gccause | 查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。 | jstat -gccause:显示gc原因 | |

| | gcnew | 查看新生代垃圾收集的情况 | jstat -gcnew pid:new对象的信息 | |

| | gcnewcapacity | 用于查看新生代的存储容量情况 | jstat -gcnewcapacity pid:new对象的信息及其占用量 | |

| | gcold | 用于查看老生代及持久代发生GC的情况 | jstat -gcold pid:old对象的信息 | |

| | gcoldcapacity | 用于查看老生代的容量 | jstat -gcoldcapacity pid:old对象的信息及其占用量 | |

| | gcpermcapacity | 用于查看持久代的容量 | jstat -gcpermcapacity pid: perm对象的信息及其占用量 | |

| | gcutil | 查看新生代、老生代及持代垃圾收集的情况 | jstat -util pid:统计gc信息统计 | |

| | printcompilation | HotSpot编译方法的统计 | jstat -printcompilation pid:当前VM执行的信息 | |

| |

| 例如: |

| |

| 查看gc 情况执行:jstat-gcutil 27777 |

| |

| ![](data:image/svg+xml;utf8,) |

| |

| ### 3、jinfo: java配置信息 |

| |

| 命令格式: |

| |

| |

| |

| | | jinfo[option] pid复制代码 | | |

| |

| |

| |

| 比如:获取一些当前进程的jvm运行和启动信息。 |

| |

| ![](data:image/svg+xml;utf8,) |

| |

| ### 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=<filename> 使用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. 复制代码 | | |

| |

| ### 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查询.复制代码 | | |

| |

| |

| |

| 后续的查找耗费最高cpu例子会用到。 |

| |

| ## 二、可视化工具 |

| |

| 对jvm监控的常见可视化工具,除了jdk本身提供的Jconsole和visualVm以外,还有第三方提供的jprofilter,perfino,Yourkit,Perf4j,JProbe,MAT等。这些工具都极大的丰富了我们定位以及优化jvm方式。 |

| |

| 这些工具的使用,网上有很多教程提供,这里就不再过多介绍了。对于VisualVm来说,比较推荐使用,它除了对jvm的侵入性比较低以外,还是jdk团队自己开发的,相信以后功能会更加丰富和完善。jprofilter对于第三方监控工具,提供的功能和可视化最为完善,目前多数ide都支持其插件,对于上线前的调试以及性能调优可以配合使用。 |

| |

| 另外对于线上dump的heap信息,应该尽量拉去到线下用于可视化工具来分析,这样分析更详细。如果对于一些紧急的问题,必须需要通过线上监控,可以采用 VisualVm的远程功能来进行,这需要使用tool.jar下的MAT功能。 |

| |

| ## 三、应用 |

| |

| ### 1、cpu飙升 |

| |

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

| |

| 1.找到最耗CPU的进程 |

| |

| |

| |

| | | 指令:top复制代码 | | |

| |

| |

| |

| |

| 2.找到该进程下最耗费cpu的线程 |

| |

| |

| |

| | | 指令:top -Hp pid复制代码 | | |

| |

| |

| |

| |

| |

| 3.转换进制 |

| |

| |

| |

| | | printf “%x\n” 15332 // 转换16进制(转换后为0x3be4) 复制代码 | | |

| |

| |

| 4.过滤指定线程,打印堆栈信息 |

| |

| |

| |

| | | 指令: | | jstack pid |grep 'threadPid' -C5 --color | | | | jstack 13525 |grep '0x3be4' -C5 --color // 打印进程堆栈 并通过线程id,过滤得到线程堆栈信息。复制代码 | | |

| |

| 可以看到是一个上报程序,占用过多cpu了(以上例子只为示例,本身耗费cpu并不高) |

| |

| ### 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复制代码 | | |

| |

| 上述输出信息中,最大内存对象才161kb,属于正常范围。如果某个对象占用空间很大,比如超过了100Mb,应该着重分析,为何没有释放。 |

| |

| 注意,上述指令: |

| |

| |

| |

| | | jmap -histo:live 11869 | more | | | | 执行之后,会造成jvm强制执行一次fgc,在线上不推荐使用,可以采取dump内存快照,线下采用可视化工具进行分析,更加详尽。 | | | | jmap -dump:format=b,file=/tmp/dump.dat 11869 | | | | 或者采用线上运维工具,自动化处理,方便快速定位,遗失出错时间。复制代码 | | |

| |

| |

| 4.确认资源是否耗尽 |

| |

| > * pstree 查看进程线程数量 |

| > * netstat 查看网络连接数量 |

| |

| 或者采用: |

| |

| > * ll /proc/\({PID}/fd | wc -l // 打开的句柄数 |
| > * ll /proc/\){PID}/task | wc -l (效果等同pstree -p | wc -l) //打开的线程数 |

| |

| 以上就是一些常见的jvm命令应用。 |

| |

| 一种工具的应用并非是万能钥匙,包治百病,问题的解决往往是需要多种工具的结合才能更好的定位问题,无论使用何种分析工具,最重要的是熟悉每种工具的优势和劣势。这样才能取长补短,配合使用。 |

| |

| |

| |

| |

| ## 参考文章 |

| |

| https://segmentfault.com/a/1190000009707894 |

| |

| https://www.cnblogs.com/hysum/p/7100874.html |

| |

| http://c.biancheng.net/view/939.html |

| |

| https://www.runoob.com/ |

| |

| https://blog.csdn.net/android_hl/article/details/53228348 |

| |

|

JVM的监控的更多相关文章

  1. jvm性能监控与故障处理工具

    jdk为我们提供了一系列的jvm性能监控和故障处理工具,在这里根据学习进度进行整理记录.便于之后查阅 1.jps 虚拟机进程工具  类似于Linux系统中的ps命令,用于查看虚拟机进程,常用的有以下功 ...

  2. 测者的性能测试手册:JVM的监控利器

    测者的性能测试手册:JVM的监控利器 每次聊起性能测试,最后的终结话题就是怎么做优化.其实在Java的复杂项目中都会有内存不足问题.内存泄露问题.线程死锁问题.CPU问题.这些问题工程测试或者是小压力 ...

  3. Java虚拟机性能管理神器 - VisualVM(1) 简介 - JVM轻量级监控分析神器

    目录(?)[-] 一VisualVM是什么 二如何获取VisualVM 三获取那个版本 四VisualVM能做什么 显示JAVA应用程序配置和运行时环境 显示本地和远程JAVA应用程序运行状态 监控应 ...

  4. 第八章 JVM性能监控与故障处理工具(2)

    注意:该篇博客主要记录自<深入理解java虚拟机(第二版)> 说明:关于命令行的JVM性能监控与故障处理工具见<第七章 JVM性能监控与故障处理工具(1)> 1.图像化的故障处 ...

  5. 【性能测试】:JVM内存监控策略的方法,以及监控结果说明

    JVM内存监控主要在稳定性压测期间,监控应用服务器内存泄露等问题: [JVM远程监控设置] 1.打开WAS控制台:https://ip:port/ibm/console/login.do 2.进入路径 ...

  6. JVM性能监控与故障处理命令汇总(jps、jstat、jinfo、jmap、jhat、jstack)

    给一个系统定位问题的时候,知识.经验是关键基础,数据是依据,工具才是运用知识处理数据的手段 使用适当的虚拟机监控和分析的工具可以加快我们分析数据.定位解决问题的速度,本文主要介绍了几款服 务器上常用的 ...

  7. 在k8s集群中,利用prometheus的jmx_exporter进行tomcat的JVM性能监控,并用grafana作前端展示

    查找了很多文档,没有完全达到我要求的, 于是,作了一定的调整,成现在这样. 操作步骤如下: 一,准备好两个文件. jmx_prometheus_javaagent-0.3.1.jar jmx_expo ...

  8. JVM进程状态监控

    前言 ========== 为什么需要做服务器jvm自动发现的监控呢?这个事情主要有两点原因: 1.zabbix默认监控jvm状态是使用jmx中转进行监控的,监控效率比较低下 2.zabbix使用jm ...

  9. JVM的监控命令

    JVM监控命令基本就是 jps.jstack.jmap.jhat.jstat 几个命令的使用就可以了 JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外 ...

  10. JVM内存监控:visualVM jconsole jstatd jmap

    本文是亲自测试的详细配置过程,不是转载而且linux下不需修改/etc/hosts文件 由于在建项目的需要,监控tomcat的内存使用,检查内存泄漏的情况.其实JDK自身已经提供了很多工具,都在JAV ...

随机推荐

  1. IOS自动化,使用到坐标点击,模拟器的分辨率怎么获取?

    IOS不能通过具体元素定位,就要考虑用坐标来点击,不同的模拟器分辨率不太一样,怎么获取模拟器的分辨率? 可能会想是不是和android模拟器一样,可以直接通过界面看到具体分辨率,不过ios好像不可以直 ...

  2. Flask + flask_sqlalchemy + jq 完成书籍展示、新增、删除功能

    后端代码 from flask import Flask, render_template, request, jsonify from flask_wtf.csrf import CSRFProte ...

  3. 二维数组与稀疏数组的转换---dataStructures

    首先我们看一个需求 在11 * 11 的五子棋的棋盘中 我们使用0代表十字交叉点也是无效的数据 用1代表黑棋 用2代表蓝棋 那么所看到的棋盘如下 改用数字显示后就如一下样式 现在我们需要将怎个棋盘存储 ...

  4. 安装hadoop2.9.2单机版本 jdk1.8 centos7

    安装JDK1.8 查看JDK1.8的安装 https://www.cnblogs.com/TJ21/p/13715749.html 安装hadoop 上传hadoop 下载hadoop     地址h ...

  5. 【经验总结】VSCode中找不到numpy/matplotlib/pillow,navigator没了

    在VSCode中写python时,import numpy和matplotlib总是报错找不到模块,用conda list和pip list看到都安装了numpy,前后折腾了很久遇到了好几个问题: 无 ...

  6. 【刷题-LeetCode】154 Find Minimum in Rotated Sorted Array II

    Find Minimum in Rotated Sorted Array II Suppose an array sorted in ascending order is rotated at som ...

  7. JavaFx 实现按钮防抖

    原文地址:JavaFx 实现按钮防抖 | Stars-One的杂货小窝 Android平台的APP,一般是有需要进行设置按钮的防抖(即在短时间内无法多次点击),我想在JavaFx项目中也是实现防抖功能 ...

  8. For Update 加锁分析

    MySQL InnoDB 锁 - For Update 加锁分析: 1. InnoDB锁 简单介绍 2. 当前读加锁分析:REPEATABLE-READ 可重复读.READ-COMMITTED 读已提 ...

  9. ES_AutoCheck.sh

    #!/bin/bash #@es_check #@date 2019/11/26 #@auth tigergao status=`curl -s GET "http://172.16.71. ...

  10. plsql 储存过程 参数的传递方式?

    /* 存储过程 一.oracel存储过程 1.没有返回值 return 值: 2.用输出参数来代替返回值: 3.输出参数可以有多个 二.参数的传递方式 1. 按位置传递 2. 按名字传递 3.混合传递 ...