JVM常用工具

921 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

概述

参数也了解了,命令也知道了,关键是用起来不是很方便,要是有图形化的界面就好了。接下来看看JDK官方和其它团队提供的一些图形化工具。

jconsole

JConsole工具是JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久区使用 情况、类加载情况等。

命令行中输入:jconsole。

jvisualvm

命令行中输入:jvisualvm Visual GC插件下载地址 :visualvm.github.io/pluginscent…

监控本地Java进程

可以监控本地的java进程的CPU,类,线程等。

监控远端Java进程

(1)在visualvm中选中“远程”,右击“添加”

(2)主机名上写服务器的ip地址,比如39.100.39.63,然后点击“确定”

(3)右击该主机"39.100.39.63",添加“JMX”,也就是通过JMX技术具体监控远端服务器哪个Java进程

(4)要想让服务器上的tomcat被连接,需要改一下Catalina.sh这个文件

注意下面的8998不要和服务器上其他端口冲突

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote 

-Djava.rmi.server.hostname=39.100.39.63 

-Dcom.sun.management.jmxremote.port=8998

-Dcom.sun.management.jmxremote.ssl=false 

-Dcom.sun.management.jmxremote.authenticate=true 

-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access 

-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password"

(5)在../conf文件中添加两个文件jmxremote.access和jmxremote.password

jmxremote.access

guest readonly

manager readwrite

jmxremote.password

guest guest

manager manager

授予权限:chmod 600 jmxremot

(6)将连接服务器地址改为公网ip地址

hostname -i 查看输出情况

172.26.225.240 172.17.0.1

vim /etc/hosts

172.26.255.240 39.100.39.63

(7)设置上述端口对应的阿里云安全策略和防火墙策略

(8)启动tomcat,来到bin目录

./startup.sh

(9)查看tomcat启动日志以及端口监听

tail -f ../logs/catalina.out 

lsof -i tcp:8080

(10)查看8998监听情况,可以发现多开了几个端口

lsof -i:8998 得到PID 

netstat -antup | grep PID

(11)在刚才的JMX中输入8998端口,并且输入用户名和密码则登录成功

端口:8998

用户名:manager

密码:manager

arthas

github :github.com/alibaba/art…

Arthas allows developers to troubleshoot production issues for Java applications without modifying code or restarting servers.

Arthas 是Alibaba开源的Java诊断工具,采用命令行交互模式,是排查jvm相关问题的利器。

下载安装

curl -O https://alibaba.github.io/arthas/arthas-boot.jar

java -jar arthas-boot.jar

or

java -jar arthas-boot.jar -h

# 然后可以选择一个Java进程

常用命令

具体每个命令怎么使用,可以查阅资料

version:查看arthas版本号

help:查看命名帮助信息

cls:清空屏幕

session:查看当前会话信息

quit:退出arthas客户端

---

dashboard:当前进程的实时数据面板

thread:当前JVM的线程堆栈信息

jvm:查看当前JVM的信息

sysprop:查看JVM的系统属性

---

sc:查看JVM已经加载的类信息

dump:dump已经加载类的byte code到特定目录

jad:反编译指定已加载类的源码

---

monitor:方法执行监控

watch:方法执行数据观测

trace:方法内部调用路径,并输出方法路径上的每个节点上耗时

stack:输出当前方法被调用的调用路径

......

内存分析

MAT

Java堆分析器,用于查找内存泄漏。

Heap Dump,称为堆转储文件,是Java进程在某个时间内的快照。

它在触发快照的时候保存了很多信息:Java对象和类信息。

通常在写Heap Dump文件前会触发一次Full GC。

下载地址 :www.eclipse.org/mat/downloa…

(1)获取dump文件

  • 手动
jmap -dump:format=b,file=heap.hprof 44808
  • 自动
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

(2)Dump的信息

  • All Objects

Class, fields, primitive values and references

  • All Classes

Classloader, name, super class, static fields

  • Garbage Collection Roots

Objects defined to be reachable by the JVM

  • Thread Stacks and Local Variables

The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects

(3)使用

Histogram:可以列出内存中的对象,对象的个数及其大小。

Class Name:类名称,java类名

Objects:类的对象的数量,这个对象被创建了多少个

Shallow Heap:一个对象内存的消耗大小,不包含对其他对象的引用

Retained Heap:是shallow Heap的总和,即该对象被GC之后所能回收到内存的总和
右击类名--->List Objects--->with incoming references--->列出该类的实例
右击Java对象名--->Merge Shortest Paths to GC Roots--->exclude all ...--->找到GC
Root以及原因
  • Leak Suspects:查找并分析内存泄漏的可能原因

Reports--->Leak Suspects--->Details

  • Top Consumers:列出大对象

heaphero

heaphero.io/

perfma

console.perfma.com/

GC日志分析

要想分析日志的信息,得先拿到GC日志文件才行,所以得先配置一下,根据前面参数的学习,下面的配置很容易看懂。比如打开windows中的catalina.bat,在第一行加上

-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDateStamps 
-Xloggc:$CATALINA_HOME/logs/gc.log

不同收集器日志

这样使用startup.bat启动tomcat的时候就能够在当前目录下拿到gc.log文件,可以看到默认使用的是 ParallelGC。

(1)Parallel GC 【吞吐量优先】

2019-06-10T23:21:53.305+0800: 1.303: [GC (Allocation Failure) [PSYoungGen:
65536K[Young区回收前]->10748K[Young区回收后](76288K[Young区总大小])] 65536K[整个
堆回收前]->15039K[整个堆回收后](251392K[整个堆总大小]), 0.0113277 secs] [Times:
user=0.00 sys=0.00, real=0.01 secs]

注意:

如果回收的差值中间有出入,说明这部分空间是Old区释放出来的

image.png

(2)CMS 【停顿时间优先】

参数设置:-XX:+UseConcMarkSweepGC -Xloggc:cms-gc.log

重启tomcat获取gc日志,这里的日志格式和上面差不多,不作分析。

(3)G1

G1日志格式参考链接:blogs.oracle.com/poonam/unde…

【停顿时间优先】

参数设置:-XX:+UseG1GC -Xloggc:g1-gc.log
-XX:+UseG1GC # 使用了G1垃圾收集器

# 什么时候发生的GC,相对的时间刻,GC发生的区域young,总共花费的时间,0.00478s,

# It is a stop-the-world activity and all

# the application threads are stopped at a safepoint during this time.

2019-12-18T16:06:46.508+0800: 0.458: [GC pause (G1 Evacuation Pause)

(young), 0.0047804 secs]

# 多少个垃圾回收线程,并行的时间

[Parallel Time: 3.0 ms, GC Workers: 4]

# GC线程开始相对于上面的0.458的时间刻

[GC Worker Start (ms): Min: 458.5, Avg: 458.5, Max: 458.5, Diff: 0.0]

# This gives us the time spent by each worker thread scanning the roots

# (globals, registers, thread stacks and VM data structures).

[Ext Root Scanning (ms): Min: 0.2, Avg: 0.4, Max: 0.7, Diff: 0.5, Sum: 1.7]

# Update RS gives us the time each thread spent in updating the Remembered

Sets.

[Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]

...

# 主要是Eden区变大了,进行了调整

[Eden: 14.0M(14.0M)->0.0B(16.0M) Survivors: 0.0B->2048.0K Heap:

14.0M(256.0M)->3752.5K(256.0M)]

image.png

GCViewer

java -jar gcviewer-1.36-SNAPSHOT.jar

gceasy

gceasy.io

gcplot

it.gcplot.com/