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 | 网络路由分析工具 |
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 (在线分析)
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 (在线分析)
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 (在线分析)
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 (笨马网络)
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
step2:找到该进程下最耗费cpu的线程 top -Hp pid
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 (问题分析)