JVM的监控
# 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的监控的更多相关文章
- jvm性能监控与故障处理工具
jdk为我们提供了一系列的jvm性能监控和故障处理工具,在这里根据学习进度进行整理记录.便于之后查阅 1.jps 虚拟机进程工具 类似于Linux系统中的ps命令,用于查看虚拟机进程,常用的有以下功 ...
- 测者的性能测试手册:JVM的监控利器
测者的性能测试手册:JVM的监控利器 每次聊起性能测试,最后的终结话题就是怎么做优化.其实在Java的复杂项目中都会有内存不足问题.内存泄露问题.线程死锁问题.CPU问题.这些问题工程测试或者是小压力 ...
- Java虚拟机性能管理神器 - VisualVM(1) 简介 - JVM轻量级监控分析神器
目录(?)[-] 一VisualVM是什么 二如何获取VisualVM 三获取那个版本 四VisualVM能做什么 显示JAVA应用程序配置和运行时环境 显示本地和远程JAVA应用程序运行状态 监控应 ...
- 第八章 JVM性能监控与故障处理工具(2)
注意:该篇博客主要记录自<深入理解java虚拟机(第二版)> 说明:关于命令行的JVM性能监控与故障处理工具见<第七章 JVM性能监控与故障处理工具(1)> 1.图像化的故障处 ...
- 【性能测试】:JVM内存监控策略的方法,以及监控结果说明
JVM内存监控主要在稳定性压测期间,监控应用服务器内存泄露等问题: [JVM远程监控设置] 1.打开WAS控制台:https://ip:port/ibm/console/login.do 2.进入路径 ...
- JVM性能监控与故障处理命令汇总(jps、jstat、jinfo、jmap、jhat、jstack)
给一个系统定位问题的时候,知识.经验是关键基础,数据是依据,工具才是运用知识处理数据的手段 使用适当的虚拟机监控和分析的工具可以加快我们分析数据.定位解决问题的速度,本文主要介绍了几款服 务器上常用的 ...
- 在k8s集群中,利用prometheus的jmx_exporter进行tomcat的JVM性能监控,并用grafana作前端展示
查找了很多文档,没有完全达到我要求的, 于是,作了一定的调整,成现在这样. 操作步骤如下: 一,准备好两个文件. jmx_prometheus_javaagent-0.3.1.jar jmx_expo ...
- JVM进程状态监控
前言 ========== 为什么需要做服务器jvm自动发现的监控呢?这个事情主要有两点原因: 1.zabbix默认监控jvm状态是使用jmx中转进行监控的,监控效率比较低下 2.zabbix使用jm ...
- JVM的监控命令
JVM监控命令基本就是 jps.jstack.jmap.jhat.jstat 几个命令的使用就可以了 JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外 ...
- JVM内存监控:visualVM jconsole jstatd jmap
本文是亲自测试的详细配置过程,不是转载而且linux下不需修改/etc/hosts文件 由于在建项目的需要,监控tomcat的内存使用,检查内存泄漏的情况.其实JDK自身已经提供了很多工具,都在JAV ...
随机推荐
- nuxt服务端渲染
<template> <div class="page"> page is search <ul> <li v-for="(it ...
- testng 的常用注解
常用注解如下: @BeforeSuite: 此注解的方法会在当前测试集合中的任一测试用例前执行 @AfterSuite: 此注解的方法会在当前测试集合中的所有测试程序结束后执行 @BeforeTest ...
- 代码审计入门之BlueCMS v1.6 sp1
0x00 前言 作为一名代码审计的新手,网上的大佬们说代码审计入门的话BlueCMS比较好,所以我就拿BlueCMS练练.(本人实在是一枚新手,请大佬们多多赐教) 0x01 环境准备 Phpstudy ...
- Android函数抽取壳的实现
0x0 前言 函数抽取壳这个词不知道从哪起源的,但我理解的函数抽取壳是那种将dex文件中的函数代码给nop,然后在运行时再把字节码给填回dex的这么一种壳. 函数抽取前: 函数抽取后: 很早之前就想写 ...
- Solon 开发,七、自定义注解开发汇总
Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...
- 【记录一个问题】android ndk下设置线程的亲缘性,总有两个核无法设置成功
参考了这篇文章:https://blog.csdn.net/lanyzh0909/article/details/50404664 大体的代码如下: #include <pthread.h> ...
- Floodlight+Mininet的SDN实验平台搭建初探
平台环境说明: Cpu:Intel Core 2 Duo T6570 Mem:4.00GB Os :Ubuntu 14.04 1.Floodlight Floodlight是一个比较成熟的sdn控制器 ...
- 《手把手教你》系列技巧篇(六十)-java+ selenium自动化测试 - 截图三剑客 -中篇(详细教程)
1.简介 前面我们介绍了Selenium中TakeScreenshot类来截图,得到的图片是浏览器窗口内的截图.有时候,只截浏览器窗口内的图是不够的,而且TakeScreenshot截图只针对浏览器的 ...
- [转载]Python 资源大全中文版
[转载]Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-python 是 vinta 发起维护的 Python ...
- Redis持久化----RDB和AOF 的区别
关于Redis说点什么,目前都是使用Redis作为数据缓存,缓存的目标主要是那些需要经常访问的数据,或计算复杂而耗时的数据.缓存的效果就是减少了数据库读的次数,减少了复杂数据的计算次数,从而提高了服务 ...