文章目录
性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成 Java 应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要了定位这些问题,一款优秀的性能诊断工具必不可少。本文将介绍 Java 性能诊断过程中的常用工具,并重点介绍其中的优秀代表 JProfiler 的基本原理和最佳实践(本文所做的调研基于jprofiler10.1.4)。
在 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 方法的调用次数和执行时间等。
更多可参考我之前写的文章:【JVM 监控工具】JVisualVM的使用
JProfiler
JProfiler 是由 ej-technologies 公司开发的一款 Java 应用性能诊断工具。它聚焦于四个重要主题上。
- 方法调用 - 对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法。
- 内存分配 - 通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用。
- 线程和锁 - JProfiler 提供多种针对线程和锁的分析视图助您发现多线程问题。
- 高级子系统 - 许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的 SQL 语句。JProfiler 支持对这些子系统进行集成分析。
JConsole
如果只需要诊断单机 Java 应用的性能瓶颈,上面介绍的诊断工具就已经够用了。但随着现代系统架构逐渐从单体转变为分布式、微服务,单纯使用上述工具往往无法满足需求,这时就需要借助 Jaeger、ARMS、SkyWalking 这些分布式追踪系统提供的全链路追踪功能。分布式追踪系统种类繁多,但实现原理都大同小异,它们通过代码埋点的方式记录 tracing 信息,通过 SDK 或 agent 将记录的数据传输至中央处理系统,最后提供 query 接口对结果进行展示和分析。
JProfiler是什么
JProfiler直觉式的GUI让你可以找到性能瓶颈、抓出内存漏失(memory leaks)、并解决执行绪的问题。它让你得以对heap walker作资源回收器的root analysis,可以轻易找出内存漏失;heap快照(snapshot)模式让未被参照(reference)的对象、稍微被参照的对象、或在终结(finalization)队列的对象都会被移除;整合精灵以便剖析浏览器的Java外挂功能。
功能
-
本地会话实时分析模式
用户一旦定义好了其应用程序启动方式,JProfiler即能对之进行设置,用户即刻便能从设置好的JVM中看到实时数据。用户若不想进行会话配置,其可以从多个IDE插件中选择其最喜欢的那个对应用程序进行配置。 -
远程会话实时分析模式
通过修改Java开始命令行方式的VM参数,用户可使任意Java应用程序监听来自的JProfiler GUI的连接。该设置程序不但可以在本地计算机上运行,还可以在网络中作为某个设置程序的附加程序使用。此外,JProfiler还提供了相当多的集成向导,可用于主流的可以帮助用户安装和设置其应用程序的应用程序服务器。 -
离线分析模式
用户无需通过JProfiler GUI连接应用程序即可对之进行设置。在离线设置模式下,用户可以使用功能强大的JProfiler触发系统或者JProfiler’ API对设置代理进行控制,然后将快照保存入磁盘。稍后用户便可使用命令行导出工具或者蚂蚁任务导出工具,在JProfiler GUI或编程方式的设置导出视图中打开这些快照。 -
快照比较
在JProfiler中,用户可以将当前的所有设置数据保存为一个快照存入磁盘中。JProfiler提供了丰富的比较功能以对比两个或者多个快照之间的不同。用户可从编程的命令行比较工具和ant task比较工具中选择其一创建对比报告。 -
查看HPROF快照
JProfiler能打开用JVM工具(比如jconsole、 jmap或通过-XX:+HeapDumpOnOutOfMemoryError JVM参数触发)创建的HPROF快照文件
安装
IEAR下载插件JPrifiler
安装完插件记得重启IDEA.出现下图标准表示安装成功
congqi官网下载JProfiler客户端并安装。 官网下载地址:https://www.ej-technologies.com/download/jprofiler/files
使用
生成快照
public class vmtest { public static int i=1; public static void main(String[] args) { final long max= Runtime.getRuntime().maxMemory();//jvm的视图使用的最大内存 final long total = Runtime.getRuntime().totalMemory();//jvm初始化内存 final int cpu = Runtime.getRuntime().availableProcessors();//cpu核数 System.out.println("虚拟机获得最大内存"+(max/1024/1024)+"m"); System.out.println("初始最大内存"+(total/1024/1024)+"m"); System.out.println("本机核数:"+cpu); String s = new String(); while(true){ final byte[] bytes = new byte[1024 * 1024*1024]; } }}
配置VM
运行程序
我们预期效果达到,堆内存超出。
打开项目目录找到生成的快照,并用JProfiler工具打开
进入JProfiler
查看堆中的实例
查看在哪里报错
本地运行
进入JProfiler
可以查程序运行时的实时数据
生成快照
进入JProfiler
可以查程序运行时的实时数据
生成快照
来源地址:https://blog.csdn.net/u011397981/article/details/131210536