JVM性能分析工具 Jprofiler
Java 性能诊断工具简介
在 Java 的世界里,有许多诊断工具可供选择,既包括像 jmap、jstat 这样的简单命令行工具,又包括 JVisualvm、JProfiler 等图形化综合诊断工具,同时还有 SkyWalking、ARMS 这样的针对分布式应用的性能监控系统。
简单命令行工具
JDK 内置了许多命令行工具,它们可用来获取目标 JVM 不同方面、不同层次的信息。
- jinfo - 用于实时查看和调整目标 JVM 的各项参数。
- jstack - 用于获取目标 Java 进程内的线程堆栈信息,可用来检测死锁、定位死循环等。
- jmap - 用于获取目标 Java 进程的内存相关信息,包括 Java 堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
- jstat - 一款轻量级多功能监控工具,可用于获取目标 Java 进程的类加载、JIT 编译、垃圾收集、内存使用等信息。
- jcmd - 相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计、JFR、内存使用、垃圾收集、线程堆栈、JVM 运行时间等信息。
图形化综合诊断工具
使用上述命令行工具或组合能帮您获取目标 Java 应用性能相关的基础信息,但它们存在下列局限:
- 无法获取方法级别的分析数据,如方法间的调用关系、各方法的调用次数和调用时间等(这对定位应用性能瓶颈至关重要)。
- 要求用户登录到目标 Java 应用所在的宿主机上,使用起来不是很方便。
- 分析数据通过终端输出,结果展示不够直观。
JVisualvm
JVisualvm 是 JDK 内置的可视化性能诊断工具,它通过 JMX、jstatd、Attach API 等方式获取目标 JVM 的分析数据,包括 CPU 使用率、内存使用量、线程堆栈信息等。此外,它还能直观地展示 Java 堆中各对象的数量和大小、各 Java 方法的调用次数和执行时间等。
JProfiler
JProfiler 是一款 Java 应用性能诊断工具。它聚焦于四个重要主题上。
- 方法调用 - 对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法。
- 内存分配 - 通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用。
- 线程和锁 - JProfiler 提供多种针对线程和锁的分析视图助您发现多线程问题。
- 高级子系统 - 许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的 SQL 语句。JProfiler 支持对这些子系统进行集成分析。
分布式应用性能诊断
如果只需要诊断单机 Java 应用的性能瓶颈,上面介绍的诊断工具就已经够用了。但随着现代系统架构逐渐从单体转变为分布式、微服务,单纯使用上述工具往往无法满足需求,这时就需要借助 Jaeger、ARMS、SkyWalking 这些分布式追踪系统提供的全链路追踪功能。分布式追踪系统种类繁多,但实现原理都大同小异,它们通过代码埋点的方式记录 tracing 信息,通过 SDK 或 agent 将记录的数据传输至中央处理系统,最后提供 query 接口对结果进行展示和分析。
JProfiler简介
JProfiler是一款性能瓶颈分析工具,其特点:
- 使用方便
- 界面操作友好
- 对被分析的应用影响小
- CPU,Thread,Memory分析功能尤其强大
- 支持对jdbc,noSql, jsp, servlet, socket等进行分析
- 支持多种模式(离线,在线)的分析
- 跨平台
下载地址:http://www.sd173.com/soft/10427.html
链接:https://pan.baidu.com/s/1WXCc4FMOC3QQtjkhY4Qeow
提取码:5xrm
版本:JProfiler 12.0.4
JProfiler功能介绍
功能面板介绍
1、Telemetries(遥测)
2、Live memory (实时内存)
JProfiler 的内存视图部分可以提供动态的内存使用状况更新视图和显示关于内存分配状况信息的视图。所有的视图都有几个聚集层并且能够显示现有存在的对象和作为垃圾回收的对象。
- All Objects 所有对象:显示所有加载类的列表和堆上分配的实例数。在最上方还可以选择按不同类型进行查看,如类、包、组件等。
- Record objects 记录的对象 :显示类或所有已记录对象的包。你可以标记出当前值并且显示差异值。
- Allocation call tree 分配调用树 :是显示请求树或者方法、类、包或对已选择类有带注释的分配信息的J2EE组件。
- Allocation hot spots 分配热点 :显示所选类的对象被分配在哪儿的方法列表。注意:分配至少占总数的1%的方法才会被显示。
- Class Tracker 类追踪器
3、Heap walker (堆遍历器)
在JProfiler的堆遍历器(Heap walker)中,你可以对堆的状况进行快照并且可以通过选择步骤下寻找感兴趣的对象。堆遍历器有七个视图:
- Classes 类 :显示所有类和它们的实例。
- Allocations 分配 :为所有记录对象显示分配树和分配热点。
- Biggest Objects 大对象:显示占用内存多的对象
- References 引用 :为单个对象和“显示到垃圾回收根目录的路径”提供索引图的显示功能。还能提供合并输入视图和输出视图的功能。
- Time 时间 :显示一个对已记录对象的解决时间的柱状图。
- Inspections 检查
- Graph 图表
4、CPU views (CPU视图)
JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。CPU视图部分包括:
- Call tree 访问树:显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分
- Hot spots 热点 :显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求,JDBC,JMS和JNDI服务请求以及按照URL请求来进行计算。
- Call graph 调用图 :显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。
- Call Tracer 调用跟踪器
- JavaScript XHR
5、Threads (线程)
对线程剖析,JProfiler提供以下视图:
(1) Thread history 线程历史:默认的就是历史视图,在这里可以观察到程序中所使用的线程历史记录。不同的颜色代表不同意义。
- 绿色表明线程正在运行并能接收CPU时间,不表明线程正在消耗CPU时间,只表明线程准备运行并且没有阻塞或睡眠。线程被分配了多少CPU时间,依赖于不同的其它元素,如总的系统负载,线程优先级和调度的运算法则。
- 橙色表示线程正在等待。线程正在睡眠并等待计时器或其它线程唤醒
- 红色表示线程阻塞。线程尝试进入同步代码块或有其它线程控制的同步方法
- 亮蓝色表示线程正在Net I/O操作,线程在等待Java库的网络操作完成。在线程监听socket连接或者等待读写数据到socket中时,会产生这种状态。
(2) Thread monitor 线程Monitor
使用监控当前线程时要注意:如果你监控的是Java1.5或以上版本,屏幕的上半部分就显示线程 列表,屏幕的下半部分显示所选线程的线程创建堆栈跟踪。堆栈跟踪只有线程创建时记录CPU数据才会显示。
(3) Thread dumps 监控死锁
死锁根据以下情况进行分析:
- 在Java平台上建立的最初的同步机制,如:使用同步的关键词。
- 在java.util.concurrent中的锁机制,不使用对象的监控,而是不同的实现机制。
- 在死锁中的线程以紫色的矩形表示
- 在死锁中的监视器以灰色的矩形表示
- 监控器的所有权用实线箭头表示
- 导致线程死锁的阻塞原因使用虚线箭头来表示
深入分析线程,可以在"Monitors & locks"中查看。
6、Monitors & locks (Monitor&锁)
- Current Locking Graph 当前锁状态图
- Current Monitors 目前使用的监测器:显示目前使用的监测器并且包括它们的关联线程。
- Locking History Graph 锁状态历史图
- Monitor History 历史检测记录:显示重大的等待事件和阻塞事件的历史记录。
- Monitor Usage Statistics 监测使用状态 :显示分组监测,线程和监测类的统计监测数据。
7、Databases (数据库)
8、JEE & Probes(JEE&探针)
9、MBeans
Jprofiler创建工程
1、使用jprofiler自带的例子工程
JProfier采集方式分为两种:Sampling(样本采集)和Instrumentation
- Sampling: 类似于样本统计, 每隔一定时间(5ms)将每个线程栈中方法栈中的信息统计出来。优点是对应用影响小,缺点是一些数据/特性不能提供(例如:方法的调用次数)
- Instrumentation: 在class加载之前,JProfier把相关功能代码写入到需要分析的class中,对正在运行的jvm有一定影响。优点: 功能强大,但如果需要分析的class多,那么对应用影响较大,一般配合Filter一起使用。所以一般JRE class和framework的class是在Filter中通常会过滤掉。
2、创建一个监视本地服务的jprofiler工程
结合开发工具idea即可。
① 首先给自己电脑下载JProfiler软件,记录你的安装目录;
② 给idea安装JProfiler的插件
③ 安装好后重启idea,给idea配置JProfiler的执行程序,如下图,这里选择你自己本地安装的JProfiler软件安装目录bin里的.exe;点击apply;
④ 点击下图中圈出的按钮,运行你的项目,就会启动你的 JProfiler,对项目运行状况进行实时监测分析
3、创建一个监视远程服务的jprofiler工程
JProfiler如何使用
Live memory 分析内存情况
1、在这里可以查看程序使用内存的情况,如果发现自己的方法在这里占有内存很大或是在某个时间段突然增加,就可以关注这个类或方法,是不是在写这个方法时用了占用大量内存的手法。在这里还可以跟踪到类源代码和byte code。
2、这里在系统运行后可以使用按钮,以当前为参照对象,动态的观察内存使用变化。其中绿色为参考时间点,褐色为当前时间的内存使用情况。这样就可以观察内存的使用,对象的创建和gc的使用情况等。
3、数量监控很重要,如果你使用了单例,那么你只会看到有一个对象存在,如果多了就说明程序有问题。同样,如果应用进行了一系列的操作,检查一下该销毁的对象是否还继续存在,如果没有释放,就得考虑是否存在内存溢出了。
Heap walker分析堆遍历
可以查找某个对象的引用情况,即:当你发现某个该释放的对象没有释放,就可以看下哪个实例在引用它,找到了根即找到了溢出点。在“Live memory”界面中右键选择你要监控的对象,选择第一项"Take Heap Snapshot for Selection"(在堆遍历器中显示所选内容),选择完成后会进入"Heap walker"界面,然后选择顶部的"References"(引用)即可。
CPU views 分析CPU情况
在这里可以观察某个时间段内方法对于cpu的使用情况,如果某个方法对cpu长时间的高频率占有,那程序肯定会慢,这时就要检查该方法是否有什么非常耗时的计算。例如:在使用swing的事件线程中进行了复杂运算,长时间占有cpu,这时就要考虑对事件进行多线程操作等。
Threads 分析线程情况
使用死锁分析可以很快的进行线程逻辑定位,直观图形化可以使用死锁的原因一目了然。另外可以在"Monitors & locks"里的"Monitor usage statistics"(Monitor使用情况统计)进行线程操作频繁度统计,能很好的帮助对程序进行的理解和性能分析。
JProfiler分析案例