美文网首页java
JVM系列(2) JVM监控工具

JVM系列(2) JVM监控工具

作者: suxin1932 | 来源:发表于2020-02-16 18:35 被阅读0次

    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 (问题分析)

    相关文章

      网友评论

        本文标题:JVM系列(2) JVM监控工具

        本文链接:https://www.haomeiwen.com/subject/icjmfhtx.html