JProfiler

业界领先的 Java 性能分析工具

JProfiler 是业界领先的 Java 性能分析工具,帮助开发者快速定位性能瓶颈, 优化应用程序性能,提升用户体验。支持本地和远程分析,适用于各种 Java 应用场景。

JProfiler聚焦于四个重要主题上:

  • 方法调用 - 对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法。
  • 内存分配 - 通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用。
  • 线程和锁 - JProfiler 提供多种针对线程和锁的分析视图助您发现多线程问题。
  • 高级子系统 - 许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的 SQL 语句。JProfiler 支持对这些子系统进行集成分析。
JProfiler agent

JProfiler agent 是一个本地库,它可以在 JVM 启动时通过参数-agentpath:进行加载或者在程序运行时通过JVM Attach 机制进行加载。Agent 被成功加载后,会设置JVMTI环境,监听虚拟机产生的事件,如类加载、线程创建等。例如,当它监听到类加载事件后,会给这些类注入用于执行度量操作的字节码。

JProfiler UI

JProfiler UI 是一个可独立部署的组件,它通过 socket 和 agent 建立连接。这意味着不论目标 JVM 运行在本地还是远端,JProfiler UI 和 agent 间的通信机制都是一样的。 JProfiler UI 的主要功能是展示通过 agent 采集上来的分析数据,此外还可以通过它控制 agent 的采集行为,将快照保存至磁盘,展示保存的快照。

命令行工具

JProfiler 提供了一系列命令行工具以实现不同的功能。

  • jpcontroller - 用于控制 agent 的采集行为。它通过 agent 注册的 JProfiler MBean 向 agent 传递命令。
  • jpenable - 用于将 agent 加载到一个正在运行的 JVM 上。
  • jpdump - 用于获取正在运行的 JVM 的堆快照。
  • jpexport & jpcompare - 用于从保存的快照中提取数据并创建 HTML 报告。
安装配置

JProfiler 同时支持诊断本地和远程 Java 应用的性能。如果您需要实时采集并展示远程 JVM 的分析数据,需要完成以步骤:

  1. 在本地安装 JProfiler UI。
  2. 在远程宿主机上安装 JProfiler agent 并让其被目标 JVM 加载。
  3. 配置 UI 到 agent 的连接。
下面介绍一下JProfiler 的设置
数据采集模式

JProfier 提供两种数据采集模式 Sampling 和 Instrumentation。

  • Sampling - 适合于不要求数据完全精确的场景。优点是对系统性能的影响较小,缺点是某些特性不支持(如方法级别的统计信息)。
  • Instrumentation - 完整功能模式,统计信息也是精确的。缺点是如果需要分析的类比较多,对应用性能影响较大。为了降低影响,往往需要和 Filter 一起使用。

由于我们需要获取方法级别的统计信息,这里选择了 Instrumentation 模式。同时配置了 Filter,让 agent 只记录位于 Java 包com.aliyun.openservices.aliyun.log.producer下的类和类com.aliyun.openservices.log.Client的 CPU 分析数据。

应用启动模式

通过为 JProfiler agent 指定不同的参数可以控制应用的启动模式。

  • 等待模式 - 只有在 Jprofiler GUI 和 agent 建立连接并完成分析配置设置后,应用才会真正启动。在这种模式下,您能够获取应用启动时期的分析数据。对应的命令为-agentpath:=port=8849
  • 立即启动模式 - 应用会立即启动,Jprofiler GUI 会在需要时和 agent 建立连接并设置分析配置。这种模式相对灵活,但会丢失应用启动初期的分析数据。对应的命令为-agentpath:=port=8849,nowait
  • 离线模式 - 通过触发器记录数据、保存快照供事后分析。对应的命令为-agentpath:=offline,id=xxx,config=/config.xml

⠀因为是在测试环境,同时对应用启动初期的性能也比较关注,这里选择了默认的等待模式。

使用 JProfiler 诊断性能

在完成 JProfiler 的设置后,便可以对 Producer 的性能进行诊断。

Overview

在概览页我们可以清晰的看到内存使用量、垃圾收集活动、类加载数量、线程个数和状态、CPU 使用率等指标随时间变化的趋势。

CPU views

CPU views 下的各个子视图展示了应用中各方法的执行次数、执行时间、调用关系等信息,能帮我们定位对应用性能影响最大的方法。

Call Tree

Call tree 通过树形图清晰地展现了方法间的层次调用关系。同时,JProfiler 将子方法按照它们的执行总时间由大到小排序,这能让您快速定位关键方法。

对于 Producer 而言,方法SendProducerBatchTask.run()耗时最多,继续向下查看会发现该方法的主要时间消耗在了执行方法Client.PutLogs()上。

Hot Spots

如果您的应用方法很多,且很多子方法的执行时间比较接近,使用 hot spots 视图往往能助您更快地定位问题。该视图能根据方法的单独执行时间、总执行时间、平均执行时间、调用次数等属性对它们排序。其中,单独执行时间等于该方法的总执行时间减去所有子方法的总执行时间。

在该视图下,可以看到Client.PutLogs()LogGroup.toByteArray()SamplePerformance$1.run()是单独执行时间耗时最多的三个方法。

Call Graph

找到了关键方法后,call graph 视图能为您呈现与该方法直接关联的所有方法。这有助于我们对症下药,制定合适的性能优化策略。

这里,我们观察到方法Client.PutLogs()执行的主要时间花费在了对象序列化上,因此性能优化的关键是提供执行效率更高的序列化方法。

Live memory

Live memory 下的各个子视图能让您掌握内存的具体分配和使用情况,助您判断是否存在内存泄漏问题。

All Objects

All Objects 视图展示了当前堆中各种对象的数量和总大小。由图可知,程序在运行过程中构造出了大量 LogContent 对象。

Allocation Call Tree

Allocation Call Tree 以树形图的形式展示了各方法分配的内存大小。可以看到,SamplePerformance$1.run()SendProducerBatchTask.run()是内存分配大户。

Allocation Hot Spots

如果方法比较多,您还可以通过 Allocation Hot Spots 视图快速找出分配对象最多的方法。

Thread History

线程历史记录视图直观地展示了各线程在不同时间点的状态。

不同线程执行的任务不同,所展现的状态特征也不同

  • 线程pool-1-thread-会循环调用producer.send()方法异步发送数据,它们在程序刚启动时一直处于运行状态,但随后在大部分时间里处于阻塞状态。这是因为 producer 发送数据的速率低于数据的产生速率,且单个 producer 实例能缓存的数据大小有限。在程序运行初始,producer 有足够空间缓存待发送数据,所以pool-1-thread-一直处于运行状态,这也就解释了为何程序在刚启动时 CPU 使用率较高。随着时间的推移,producer 的缓存被逐渐耗尽,pool-1-thread-必须等到 producer “释放”出足够的空间才有机会继续运行,这也是为什么我们会观察到大量线程处于阻塞状态。
  • aliyun-log-producer-0-mover负责将超时 batch 投递到发送线程池中。由于发送速率较快,batch 会因缓存的数据达到了上限被pool-1-thread-直接投递到发送线程池中,因此 mover 线程在大部分时间里都处于等待状态。
  • aliyun-log-producer-0-io-thread-作为真正执行数据发送任务的线程有一部分时间花在了网络 I/O 状态。
  • aliyun-log-producer-0-success-batch-handler用于处理发送成功的 batch。由于回调函数比较简单,执行时间短,它在大部分时间里都处于等待状态。
  • aliyun-log-producer-0-failure-batch-handler用于处理发送失败的 batch。由于没有数据发送失败,它一直处于等待状态。

通过上述分析可知,这些线程的状态特征都是符合预期的。

Overhead Hot Spots Detected

当程序运行结束后,JProfiler 会弹出一个对话框展示那些频繁被调用,但执行时间又很短的方法。在下次诊断时,您可以让 JProfiler agent 在分析过程中忽略掉这些方法以减轻对应用性能的影响。

常见问题

运行终端.app,执行sudo xattr -rc /Applications/xxx.app,路径改成安装包的路径;
完成后再次打开应用程序,你会看到一个信息确认框,大意是提示运行该程序有风险,点击「打开」即可。

点击查看详细帮助

按住 Control 键,鼠标单击该软件,在弹出的菜单中选择 打开;或 鼠标右键 点击该软件,选择「显示包内容」,
然后进入 Contents → MacOS → 按住 Control + 鼠标左键单击此目录中与该软件同名的 Unix 可执行程序;
以上操作过后,该软件会加入 macOS 内置的安全设置白名单中,下次就可以正常从启动台运行。

点击查看详细帮助

打开:偏好设置 → 隐私与安全性 → 安全性;选择任何来源

没有任何来源选项?

运行终端.app,执行下面代码:

  • 如果是 macOS 10.12 ~ 10.15.7:sudo spctl --master-disable
  • 如果是 macOS 11.0 及以上版本系统:sudo spctl --global-disable

点击查看详细帮助

  • 首先选择与自己macOS系统对应的版本,比如电脑芯片、版本等。
  • 多个破解版本存在建议使用TNT版,安装简单方便,其他的都有点复杂,对于小白用户来说有点困难。
  • 100M以内的文件在蓝筹云里、123网盘和诚通网盘,下载速度还可以。大于100M的分别在阿里云盘、百度网盘和诚通网盘;百度网盘限速严重,因此建议使用阿里网盘和诚通网盘。

本站前期的部分安装包需要密码,请尝试输入hellomac.cc。后面逐渐取消密码设置。

1、如何关闭 SIP?

首先进入回复模式:

  • 英特尔机型:重启,当屏幕彻底变黑后,赶快按住 Command + R 键,直到屏幕上出现苹果标志。如果之前没有进入过这个模式,macOS 可能需要下载一些数据,当下载完成后,macOS 将自动进入恢复模式,即 Recovery。
  • M1/M2(Apple Silicon):Mac 处于关机状态时,按住电源按钮大约 10 秒直到屏幕亮起,然后转到“选项”(Options),可能需要输入系统密码。

终端.app中运行:csrutil disable

重启!


2、关闭后有什么影响?

SIP 指的是 System Integrity Protection,即系统完整性保护。这是一个用于保护 macOS 系统文件不被篡改的安全机制,自 macOS 10.11 开始引入。当 SIP 被关闭后,macOS 会面临一定的安全风险,如果你的数据非常重要则请谨慎关闭,风险自担。

新上架 JProfiler
JProfiler

业界领先的 Java 性能分析工具

v14.0.6

点击发布需求
JProfiler
JProfiler

业界领先的 Java 性能分析工具

Texifier
Texifier

LaTeX编辑与排版工具

Serial
Serial

专业级串口调试工具

PlistEdit Pro
PlistEdit Pro

Plist 属性列表编辑工具

Valentina Studio Pro
Valentina Studio Pro

全能型数据库管理与开发利器

PrefEdit
PrefEdit

高效便捷的macOS首选项文件编辑器