Java性能调优七种武器

                    Java性能调优七种武器

目录

JDK命令行

Eclipse Memory Analyzer

JMX - Jconsole, VisualVM

Btrace

Flight Recorder Java Mission Control

JProfiler

火焰图



线上服务有时候我们会碰到下面这些问题:

  • OutOfMemoryError,内存不足

  • 内存泄露

  • 线程死锁

  • 锁争用(Lock Contention)

  • Java进程消耗CPU过高


JDK命令行

jps
主要用来输出JVM中运行的进程状态信息。语法格式如下:

jps [options] [hostid]

命令行参数选项说明如下:

-q 不输出类名、Jar名和传入main方法的参数

-m 输出传入main方法的参数

-l 输出main类或Jar的全限名

-v 输出传入JVM的参数

jstack
主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip

命令行参数选项说明如下:

-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

实例:找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
1、找出java进程Id, 通过匹配部署在服务器上的java应用名称

ps -ef | grep mibi-admin-timertask

得到进程ID为29051

2、找出该进程内最耗费CPU的线程, TIME列就是各个Java线程耗费的CPU时间

top -Hp 29051

这里得到的pid为:29168
3、得到该pid的十六进制值

printf "%x\n" 29168

该十六进制值为71f0
4、输出进程29051的堆栈信息(是进程pid,不是线程pid)

 ​​​​jstack 29051 | grep 71f0 

可以看到CPU消耗在某个类的方法上,然后匹配相应代码即可。


jstat (JVM统计监测工具)
 语法格式如下:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。
例如:

jstat -gcutil 62147 1000


jmap 内存使用情况,导出内存镜像文件
 查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况

jmap -heap pid

用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:

jmap -dump:format=b,file=dumpFileName pid


Eclipse Memory Analyzer(查看内存泄漏)


(线上服务不推荐该工具,因为当dump下来内存数据文件时,可能因为文件过大直接压垮系统,影响线上的服务)
官网:
https://www.eclipse.org/mat/

在Eclipse中安装说明

打开Eclipse->Help->Eclipse Marketplace,搜索memory,如下:
 

Java性能调优七种武器_第1张图片

打开eclipse后,点击eclipse的file---->open file 找到指定生成的hprof文件位置打开,生成下图报表,选择默认选项 Leak Suspects Report,打开之后的主界面如下图:

第一个菜单:Overview,显示了概要信息,并且展示了MAT常用功能,如下图:

Java性能调优七种武器_第2张图片



第二个菜单:Histogram,显示了每个类实例的数量和大小,大小包括ShallowHeap,和RetainedHeap,如下图:

Java性能调优七种武器_第3张图片



第三个菜单:Dominator_tree,列出HeapDump中处于活跃状态的最大的对象,默认按着RetainedHeap排序,很容易找到占用内存最多的对象,如下图:

Java性能调优七种武器_第4张图片


第四个菜单:OQL,面向对象查询语言(OQL),类似SQL,将类当做表,一个对象当做一条记录行,成员变量当做表中的字段。点击红色叹号(Execute Query),进行查询,如下图:
Java性能调优七种武器_第5张图片

第五个菜单:ThreadOverride,查看生成HeapDump文件的时候,线程的运行情况,可以用于线程分析,如下图:
Java性能调优七种武器_第6张图片

 

采用下面的“三步曲”来分析内存泄露问题:

第一步,对问题发生时刻的系统内存状态获取一个整体印象。

第二步,找到最有可能导致内存泄露的元凶,通常也就是消耗内存最多的对象。

最后,去查看这个内存消耗大户的具体情况,看看是否有什么异常的行为。


JMX - Jconsole, VisualVM

Jconsole官网:https://docs.oracle.com/javase/tutorial/jmx/
VisualVM官网:https://visualvm.github.io/

Jconsole
在java的bin目录下即可打开,连接你想连接的Java应用程序。
通过Jconsole工具,可以查看Java应用程序的运行概况,可以监控堆信息、永久区使用情况、类加载情况。
 

Java性能调优七种武器_第7张图片

 

Java性能调优七种武器_第8张图片


如果需要使用JConsole连接远程进程,需要在启动服务器上的java应用时添加参数:

-Dcom.sun.management.jmxremote.host=127.0.0.1
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8888
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

进行远程连接时,只需要填写如下远程进程即可:

127.0.0.1:8888

内存监控页面点击"执行GC"按钮,可以强制应用程序执行一次Full Gc。
线程监控页面点击"检测到死锁"按钮,可以自动检测多线程应用程序的死锁情况。
 

VisualVM
可以替代jstat、jmap、jhat、jstack,甚至可以代替Jconsole。在java的bin目录打开后,可以进行本地连接,也可以进行远程连接,远程连接的配置跟上面的Jconsole远程连接时一样。
从java1.7开始,visual vm 就作为JDK的一部分了,打开bin目录下的jvisualvm.exe。

Java性能调优七种武器_第9张图片

Thread Dump和分析
线程页面提供详细的线程信息,单击“线程Dump”按钮可以导出当前所有线程的堆栈信息,相当于jstack命令。
如果Visual Vm在当前程序中找到死锁,会在页面中给予提示。

Java性能调优七种武器_第10张图片

性能分析
抽样页面中CPU按钮可以查看CPU占用时间定位到方法,内存按钮可以查看当前程序的堆信息。
CPU采样器可以定位到系统中最消耗资源的方法。另外,如果想统计JDK内置对象的函数调用统计,请勾选设置进行配置。

Java性能调优七种武器_第11张图片

内存采样器可以实时查看系统中实例的分布情况。

Java性能调优七种武器_第12张图片


内存快照分析
下图为获取当前应用程序的内存快照,相当于jmap命令。

Java性能调优七种武器_第13张图片

内存快照分析如下图,基本功能页:概要、类、实例数和OQL控制台。

Java性能调优七种武器_第14张图片

类页面可以对两个不同的内存快照文件进行比较,帮助我们快速分析同一应用程序在运行的不同时刻,内存数据产生的变化。

Java性能调优七种武器_第15张图片



Btrace

可以做更精细化的追踪控制。在不停机的情况下,通过字节码注入动态监控系统的运行情况,可以跟踪指定的方法调用、构造函数调用和系统内存等信息。
在Visual VM中安装Btrace插件,点击工具,然后查看可用插件,就能进行安装了。
Java性能调优七种武器_第16张图片
点击“Trace application"进入BTrace插件页面,在代码区完成Btrace脚本的编写,单击start按钮将BTrace脚本注入选中应用程序。

Java性能调优七种武器_第17张图片
Java性能调优七种武器_第18张图片

@OnMethod注释指定要监控的类和方法名称。
@ProbeClassName 类名
@ProbeMethodName 方法名
AnyType[]  传递给方法的参数
下面的脚本是监控每次涉及匹配到的方法的调用时,输出相关信息。
Java性能调优七种武器_第19张图片
更多详情请参考下面链接:
https://blog.csdn.net/ZYC88888/article/details/81662671


Flight Recorder   Java Mission Control

在java的bin目录下打开jmc.exe这个程序。选中左侧的某个进程的MBean服务器,如下图:

Java性能调优七种武器_第20张图片

通过左下侧的tab页切换,可以显示内存、线程、诊断命令等。
 

Flight Recorder(飞行记录器)

通过记录程序在一段时间内的运行情况,将记录结果进行分析和展示,可以更进一步对系统的性能进行分析和诊断。前提:要监控的程序必须带以下参数启动:

-XX:+UnlockCommercialFeatures -XX:+FlightRecorder

点击启动飞行器,进行一分钟的数据采集,显示常规的内存和CPU信息,还有代码、线程和I/O等比较重要的信息。

Java性能调优七种武器_第21张图片


更多学习资料可以参考:
https://github.com/JDKMissionControl/jmc 


JProfiler

最强大,产品化最好,但是收费。
安装教程:https://blog.csdn.net/shiyong1949/article/details/52574896
windows下的使用教程:https://blog.csdn.net/zljain/article/details/81777987


火焰图


功能:快速找到性能瓶颈,改善接口性能。
火焰图是一个SVG格式的图片,图上的每个色块代表的是一个线程栈帧,纵轴方向从下往上表示的是函数调用栈,而横轴方向色块的宽度表示的是函数调用占用CPU的比例。
idea也支持打开火焰图(windows系统的不支持):
command + shift + alt + / ,快捷键打开下图:

Java性能调优七种武器_第22张图片

选择Experimental features,对idea.profiler.enabled打勾,配置好,如下图:
Java性能调优七种武器_第23张图片

执行携带Async Profiler的项 

Java性能调优七种武器_第24张图片

分析火焰图

得到的图片示例如下,像一团火焰,因此得名火焰图:
Java性能调优七种武器_第25张图片

y轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

x轴表示抽样数,如果一个函数在x轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。

除了idea自带,可以在linux环境下载、编译、配置Async Profiler,参考如下:
https://www.jianshu.com/p/3d67d4eaf649

你可能感兴趣的:(Java_JVM)