性能诊断 JProfiler 工具使用
JProfiler
是一个重量级的JVM
监控工具,提供对JVM
精确监控,其中堆遍历、CPU
剖析、线程剖析看成定位当前系统瓶颈的得力工具。可以统计压测过程中JVM
的监控数据,定位性能问题。
官网地址:Java Profiler - JProfiler (ej-technologies.com)
安装方法
- JProfiler Help - Installing (ej-technologies.com)
介绍
JProfiler
是一个专业的工具,用于分析正在运行的JVM
内部发生的事情。您可以在 开发,用于质量保证,并在生产系统遇到问题时执行消防任务。
方法调用
CPU
分析:可以用不同的方式度量和可视化方法调用。对方法调用的分析可以帮助您了解应用程序正在做什么,并找到改进其性能的方法。
对象内存分配
- 分析堆上的对象的分配、引用链和垃圾收集属于“内存分析”的范畴。此功能使您能够修复内存泄漏,通常使用更少的内存并分配更少的临时对象。
线程和锁
- 线程可以持有锁,例如通过在对象上同步。当多个线程合作时,可能会发生死锁,
JProfiler
可以为您可视化它们。此外,锁可以是争用的,这意味着线程必须等待才能获得锁。JProfiler
提供了对线程及其各种锁定情况的洞察。
高级子系统
- 许多性能问题发生在更高的语义级别上。例如,对于
JDBC
调用,您可能希望找出哪个SQL
语句是最慢的。对于这样的子系统,JProfiler
提供了将特定的有效负载附加到调用树的“探测”。
Jprofiler 设置
数据采集模式
JProfier
提供两种数据采集模式Sampling
和Instrumentation
。
Sampling
- 适合于不要求数据完全精确的场景。优点是对系统性能的影响较小,缺点是某些特性不支持(如方法级别的统计信息)。Instrumentation
- 完整功能模式,统计信息也是精确的。缺点是如果需要分析的类比较多,对应用性能影响较大。为了降低影响,往往需要和Filter
一起使用。
快照
生成堆快照
- 在拍摄堆快照会产生过多开销或消耗过多内存的情况下,您可以 使用
JVM
作为内置功能提供的HPROF
堆快照。 由于此操作不需要分析代理,因此这对于分析内存问题很有趣 在生产环境中运行的JVM
中。
使用 JProfiler
,有三种方法可以获取此类快照:
-
对于实时会话,
JProfiler GUI
在主菜单中提供了一个操作来触发HPROF
堆转储。
-
JProfiler
有一个特殊的“内存不足异常”触发器,用于在抛出 时保存HPROF
快照。这对应于虚拟机参数-XX:+HeapDumpOnOutOfMemoryError
由
HotSpot JVM
支持。Dump
文件 是在OOM
内存溢出的时候,自动Dump
文件转存快照的,配置JVM
参数 ,就能够在发生Out of Memory
错误的时候,就是把当前堆栈信息转存为快照Dump
文件
-
JDK
中的jmap
可执行文件可用于从正在运行的JVM
中提取HPROF
堆转储。JProfiler
包含比jmap
更通用的命令行工具。它 允许您选择一个进程,可以连接到在Windows
上作为服务运行的进程,没有问题 混合了32
位/64
位JVM
和自动编号的HPROF
快照文件。使用选项执行它以获取更多信息。jpdump help
JDK 飞行记录器快照
-
JDK
包括JDK
飞行记录器 (JFR
) 机制,用于捕获有关方法的事件 执行、对象分配和JVM
的其他重要子系统,并将它们保存到快照中。 生产环境可以选择连续使用此技术,以最大程度地减少开销并提供数据 故障 排除。可以使用以“JFR”开头的命令在JDK
中记录和保存JFR
快照。 -
使用
JProfiler
,您可以打开JDK
飞行记录器快照来分析记录的数据。打开JFR
时 快照,只有一小部分JProfiler
的视图将显示在对应于JFR
记录中可用的数据类型。
Jprofiler分析Dump文件例子
分析大对象来源
-
预估对象内存大小
-
calculate estimated retained size
预估内存对象使用大小
-
按照
Size
排序,可以看到TableClazzDO
占用很多内存
Incomming References
找引用当前对象的对象
- 首先 选中对象,点击右键,
Use select Objects
;选择incoming references
找到对象引用的地方
- 逐个查找
- 查看有问题的代码是下面写的这个测试代码
@Override
public void outOfMemory() {
List<TableClazzDO> userList = new ArrayList();
while (true) {
List<TableClazzDO> tableClazzDOS = tableClazzDOMapper.selectByExample(new TableClazzDOExample());
userList.addAll(tableClazzDOS);
}
}
profile 大对象寻找法
使用Biggest Objects
-
点开大对象进行分析, 同样的
Used Selected Objects
-
点击
Incomming References
查找对象引用信息 -
和上面一样点看逐个查找
Outgoing References 找该对象引用的所有对象
-
同样的
Used Selected Objects
-
后选择
Outgoing References
出引用信息 -
然后点开分析该对象到底引用了哪些对象,可以看到具体的对象信息
用Graph 查找对象源
- 先查找
Incomming References
找到对象被谁引用 - 找到想要追查的对象后, 选择
User Selected Objects
- 后点击
Show In Graph
定位线程及Class
信息 - 然后根据 数据源
Heap Walker
定位到问题的Class
类信息及具体的行信息
遥测
- 监视一段时间内的标量测量值,例如使用的堆大小
完整视图显示具有当前值的图例,并且可能具有比概览中可见的选项更多的选项。 例如,“内存”遥测允许选择单个内存池。
Cpu分析
- 当
JProfiler
测量方法调用的执行时间及其调用堆栈时,我们称之为CPU
分析。这些数据以多种方式呈现。取决于您尝试的问题 解决,一个或另一个演示文稿将最有帮助。默认情况下不记录CPU
数据, 须打开CPU
录制才能捕获用例。
调用树
- 直观地 掌握繁忙的
JVM
中的方法调用次数 - 可以知道方法调用相对于整个活动中的重要性 某个时间段
线程状态
- 在调用树的顶部有几个视图参数,用于更改所显示的类型和范围 分析数据。默认情况下,所有线程都是累积的。
JProfiler
基于每个线程维护CPU
数据,并且 您可以显示单个线程或线程组。
火焰图
- 查看调用树的另一种方法是作为火焰图。您可以显示整个调用树或其中的一部分 作为火焰图,通过调用关联的调用树分析
内存信息跟踪
-
选择
Telemetries-Memory
即可查看内存整体占用情况。
-
选择
Live memory-All objects
可查看当前时刻内存对象统计信息。
-
点击
Mark Current
可以创建当前时刻内存对象基线,且可以查看两次Mark
期间对象的变化情况。首次mark
-
第二次
mark