java

JVM系列(2) JVM监控工具

2020-02-16  本文已影响0人  suxin1932

1.JVM调优工具

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

1.1 常用linux分析命令

命令 作用与特点
vmstat 进程,虚拟内存,页面交换,IO读写,CPU活动等
iostat & iotop 系统IO状态信息
ifstat & iftop 实时网络流量监控
netstat 查看相关网络信息,各种网络协议套接字状态
dstat 全能型实时系统统计信息
strace 诊断,调试程序的系统调用
GDB 程序调试,coredump分析
lsof 查看系统当前打开的文件信息
tcpdump 网络抓包工具
traceroute 网络路由分析工具
jvm工具1--jmc.png jvm工具2-btrace-线上问题定位神器.png

1.2 jvm 常用命令

1.2.1 jps:查看所有 Java 进程

jps(JVM Process Status):
显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一 ID(Local Virtual Machine Identifier,LVMID)。

jps -q :只输出进程的本地虚拟机唯一 ID。
jps -l: 输出主类的全名,如果进程执行的是 Jar 包,输出 Jar 路径。
jps -v:输出虚拟机进程启动时 JVM 参数。
jps -m:输出传递给 Java 进程 main() 函数的参数。

1.2.2 jmap:java 内存映射工具 (与 jhat 配合使用)

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

如果不使用 jmap 命令,要想获取 Java 堆转储,
可以在启动时使用 -XX:+HeapDumpOnOutOfMemoryError 参数,
让虚拟机在 OOM 异常出现之后自动生成 dump 文件。

Linux 命令下可以通过 kill -3 发送进程退出信号也能拿到 dump 文件。

jmap 的作用并不仅仅是为了获取 dump 文件,
它还可以查询 finalizer 执行队列、Java 堆和永久代的详细信息,
如空间使用率、当前使用的是哪种收集器等。
和jinfo一样,jmap有不少功能在 Windows 平台下也是受限制的。
#命令格式: 
jmap [ option ] pid

#可选参数 [option]:
-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. 
#示例:
将指定应用程序的堆快照输出到桌面。
后面,可以通过 jhat、Visual VM 等工具分析该堆文件。
"jmap -dump:format=b,file=/heap.hprof 300"
jvm命令生成并分析dump文件1.png jvm命令生成并分析dump文件2.png

1.2.3 jhat:jvm堆快照分析工具

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

1.2.4 jstack :java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。
线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合.
生成线程快照的目的主要是定位线程长时间出现停顿的原因,
如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的原因。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,
就可以知道没有响应的线程到底在后台做些什么事情,或者在等待些什么资源。
#命令格式:
jstack [ option ] pid

#可选参数 [option]
-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l  长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m 打印java和native c/c++框架的所有栈信息.
-h | -help打印帮助信息
jstack--生成虚拟机当前时刻的线程快照.png

1.2.5 jstat: jvm统计信息监控工具

jstat(JVM Statistics Monitoring Tool)
使用于监视虚拟机各种运行状态信息的命令行工具。 
它可以显示本地或者远程(需要远程主机提供 RMI 支持)
虚拟机进程中的类信息、内存、垃圾收集、JIT 编译等运行数据,
在没有 GUI,只提供了纯文本控制台环境的服务器上,
它将是运行期间定位虚拟机性能问题的首选工具。

#jstat 命令使用格式:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

jstat -class vmid :显示 ClassLoader 的相关信息;
jstat -compiler vmid :显示 JIT 编译的相关信息;
jstat -gc vmid :显示与 GC 相关的堆信息;
jstat -gccapacity vmid :显示各个代的容量及使用情况;
jstat -gcnew vmid :显示新生代信息;
jstat -gcnewcapcacity vmid :显示新生代大小与使用情况;
jstat -gcold vmid :显示老年代和永久代的信息;
jstat -gcoldcapacity vmid :显示老年代的大小;
jstat -gcpermcapacity vmid :显示永久代大小;
jstat -gcutil vmid :显示垃圾收集信息;

另外,加上 -t参数可以在输出信息上加一个 Timestamp 列,显示程序的运行时间。
例子1: 收集gc信息,采样间隔时间为2000ms,收集5次.png

1.2.6 jinfo: 实时地查看和调整虚拟机各项配置参数

jinfo vmid :
输出当前 jvm 进程的全部参数和系统属性
第一部分是系统的属性,第二部分是 JVM 的参数。

#jinfo -flag <name> vmid :输出对应名称的参数的具体值。
jinfo -flag MaxTenuringThreshold 300
jinfo -flag MaxHeapSize 300
jinfo -flag PrintGC 300

#动态修改 jvm 的参数
使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用
#jinfo -flag [+|-]name vmid 开启或者关闭对应名称的参数。
jinfo  -flag  +PrintGC 300
jinfo  -flag  PrintGC 300
jvm工具3-其他.png

1.3 常用分析工具

1.3.1 gc日志分析

如何获取gc日志

#For Java 1.4, 5, 6, 7, 8 pass this JVM argument to your application: 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+PrintGC
-XX:+PrintGCTimeStamps
-XX:+PriintHeapAtGC
-verbose:gc
-Xloggc:<file-path>

#For Java 9, pass the JVM argument: 
-Xlog:gc*:file=<file-path>

#注意
上述的 file-path: is the location where GC log file will be written

1.3.1.1 gceasy (在线分析)

https://blog.gceasy.io/

1.3.1.2 gcviewer (离线分析)

https://github.com/chewiebug/GCViewer (适于JDK高版本)
https://www.tagtraum.com/gcviewer.html (适于JDK低版本)

1.3.2 堆内存 dump 文件分析

如何获取堆内存 dump 文件

#1.应用启动时添加JVM参数
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/opt/appName/heapdump.hprof (可选)
-XX:-CreateMinidumpOnCrash (windows上使用)

#2.jmap, 不推荐, 因为线上应用时, 会导致GCPause
jmap -dump:format=b,file=<file-path> <pid>

#3.jcmd
jcmd <pid> GC.heap_dump <file-path>

#4.JVisualVM图形工具采集

1.3.2.1 heaphero (在线分析)

https://blog.heaphero.io/

1.3.2.2 MAT(离线分析)

http://www.eclipse.org/mat/ (下载压缩版的)

1.3.3 线程 dump 文件(java-core)分析

如何获取线程 dump (java-core)文件

#1.jstack
jstack -l  <pid> >> <file-path>
如: jstack -l 37320 > /opt/tmp/threadDump.txt

#2.kill -3
kill -3 <pid>

#3.JVisualVM图形工具采集

1.3.3.1 fastthread (在线分析)

https://fastthread.io/

1.3.3.2 TMDA(离线分析)

https://www.ibm.com/support/pages/ibm-thread-and-monitor-dump-analyzer-java-tmda

1.3.4 国内综合分析工具(含JVM参数配置)

1.3.4.1 perfma (笨马网络)

https://www.perfma.com/

1.3.4.2 arthas

https://github.com/alibaba/arthas/blob/master/README_CN.md
https://gitee.com/arthas/arthas

1.3.5 JDK原生工具

#JVisualVM(最好配套下载各种插件, 如VisualGC):
JDK自带,功能强大,与JProfiler类似。推荐。

#Jconsole :
jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。

#JProfiler:
商业软件,需要付费。功能强大。

1.4 堆内存dump文件怎么生成和分析

#1.jmap命令(不建议)
上文已经提到, 可以利用jmap命令生成当前JVM的dmp文件,
但是, 这种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。

#方案2(建议使用): 
JVM启动时增加两个参数:
#出现 OOME 时生成堆 dump: 
-XX:+HeapDumpOnOutOfMemoryError
#生成堆文件地址:
-XX:HeapDumpPath=/home/sps/jvmlogs/

两种方式生成的堆内存文件, 可以用mat工具打开。

2.实战部分

2.1 Windows上远程连接监控Linux服务器的JVM

#1、Linux服务器上配置:
在Tomcat的tomcat-wms/bin/catalina.sh中添加
CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=6090,server=y,suspend=n -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.0.199-Dcom.sun.management.jmxremote.port=8111 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:+UnlockCommercialFeatures -XX:+FlightRecorder"

#2、添加监控的配置:
在Tomcat的tomcat-wms/bin/catalina.sh中添加
JAVA_OPTS="
-server
-Xms8192m -Xmx8192m
-XX:+UseParallelOldGC
-XX:+UseAdaptiveSizePolicy
-XX:MaxGCPauseMillis=500
-XX:ParallelGCThreads=4
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UnlockDiagnosticVMOptions
-XX:+DebugNonSafepoints
-XX:NativeMemoryTracking=detail
-Denv_param=_simulation
-Xss2m
"

#3、在Windows端连接(见下图)
Java性能调优:利用JMC分析性能
在Windows端连接远程主机.png

2.2 cpu飙升

在线上有时候某个时刻,可能会出现应用某个时刻突然cpu飙升的问题。

step1:找到最耗CPU的进程: top -d 10

每10秒更新一次top,查看整体信息.png

step2:找到该进程下最耗费cpu的线程 top -Hp pid

step2:找到该进程下最耗费cpu的线程.png

step3:转换进制 printf "%x\n" 31236 (转换后为: 0x7a04)

step4:过滤指定线程,打印堆栈信息

#命令 
jstack pid |grep 'threadPid'  -C5 --color 
#示例(31214是进程pid, '0x7a04'是进程下一个子线程pid的16进制)
jstack 31214 |grep '0x7a04'  -C5 --color

参考资源
https://www.cnblogs.com/liuxl21/p/10763293.html (JMC监控远程主机)
https://www.cnblogs.com/liangzs/p/8489321.html (jvm内存快照dump文件太大)
https://www.jianshu.com/p/a49835c7f7ed (jvm 命令行小结)
https://mp.weixin.qq.com/s/hjwkmTm2Ze6qz7lnD8ThJw (问题分析)

上一篇下一篇

猜你喜欢

热点阅读