Java Flight Recordings (JFR) — part 2 用 JFR 定位性能问题

标签: JVM JFR | 发表时间:2015-04-08 22:14 | 作者:coderbee
出处:http://coderbee.net

内容目录

一、JFR 概览

二、找出瓶颈

不同的应用有不同的瓶颈。对于有些应用,瓶颈可能是等待 I/O 或网络,可能是线程之间的同步,或者是实际的 CPU 使用。对于其他,瓶颈可能是 GC 时间。很可能应用有不止一个瓶颈。

找出应用瓶颈的一个方法是查看 Events 选项卡。这是一个高级选项卡,可以做不少事情。如下图,可以选择自己感兴趣的事件:
jfr-event-types

生成的结果图示:
jfr-thread-event

在“Graph”选项卡里,每一行是一个线程,每个线程可以有多行。在上图中,每个线程都有一行,表示 Java 应用程序的时间,在 “Event Types”选项卡里允许录制的。被选中的 Java 应用程序事件都有个重要的属性是线程失速事件。线程失速表明线程在事件期间没有运行你的应用程序,它们是持续事件。持续事件测量了应用程序没有运行的期间。

从“Event Types” 选项卡里每种颜色对应不同的事件。

Java Monitor Wait 事件表示线程在对象上等待,这通常意味着线程空闲,可能在等待任务;
如果 Java 应用程序的重要线程花费很多时间在阻塞上,表明应用的关键区域是单线程的,是个瓶颈。
花费时间越多的事件越可能是瓶颈。

绿色部分表示线程没有睡眠、等待、读或写套接字,也没有被阻塞。通常这是线程在允许应用代码。如果 Java 应用的重要线程花费大量时间而没有生成任何应用事件,那么应用的瓶颈可能代码或 CPU 自身。

注意:对于大多数 Java 应用事件类型,只有超过 20 ms 的事件将被记录(这个阀值可以在启动飞行记录时修改)。没有记录事件的区域可能是因为应用在做大量的短任务,例如读写文件(每次一小部分)或做很短时间的同步。

事件选项卡没有显示 GC 和 GC 是否可能成为瓶颈。

三、GC 性能

调优 HotSpot 垃圾收集器可以对性能有很大影响。更多信息见 Garbage Collection Tuning Guide

启动飞行记录时最好不好包括堆统计,因为这会触发额外的年老代收集。为了得到更好的抽样,让记录时间尽量长。

选择 “Memory” 选项卡然后选择“GC Times”子选项卡。GC Times 是调查 GC 整体性能影响的很好选项卡。在右上角,看“All Collections Pause Time”区域的“Average Sum of Pauses”, “Maximum Sum of Pauses”, “Total Pause Time” 的记录。“Sum of Pauses” 是应用在 GC 期间暂停的所有时间。很多 GC 在后台做大部分工作,在这些情况下,GC 的长度不要紧,要紧的是应用必须停止多长时间。因此“Sum of Pauses”是对 GC 影响的很好衡量。

下图展示了 5 分钟的飞行记录,在这个时间内,暂停的平均时间是 16 ms,最大暂停时间是 49 ms,总的暂停时间是 2秒86毫秒。
jfr-gc

通常,GC 的主要性能问题要么单次 GC 花了很长时间,要么是 GC 暂停花了很多时间(总的GC暂停)。

当单次 GC 花了太长时间时,你可能需要改变 GC 策略。不同的 GC 有不同的权衡,在暂停时间和吞吐量性能之间。更多信息见 Behavior-Based Tuning

例如,你可能需要修复你的应用以减少使用 finalizer 和/或 semi-references。

当应用花了很多时间在暂停上时,有多种方法可以变通。

一种方法是增加 Java 堆的大小。在“Garbage Collection”子选项卡估计应用使用的 Java 堆大小,加大 XmsXmx 的值。Java 堆越大,GC 时间越长。小心 Java 应用的任何内存泄露,因为那可能导致更频繁的 GC 直至抛出 OutOfMemoryError。更多信息见 Debug a Memory Leak Using Java Flight Recorder

另一种方法,为了减少 GC 次数,分配更少的临时对象。在“Allocation”选项卡,查看在记录过程中已分配了多少内存。小对象是在 TLAB 内分配,大对象在 TLAB 外分配。经常,主要的分配发生在 TLAB 内。

最后但不是最少的减少 GC 需要的方法是减少分配频率。选择“Alloc in new TLAB”选项卡,然后选择“Allocations”选项卡,查看分配的大小和有最多内存压力的栈轨迹。你可以按类查看,也可以选择“Allocation by Thread”来看哪个线程消耗了最多分配。

更多关于 JFR Allocation 选项卡的细节见 Inspect a Flight Recording

其他的一些设置可能也增加应用的 GC 性能。 Garbage Collection Tuning Guide 章节大部分都是讨论 GC 性能的。

四、同步性能

为了调试 Java 应用的同步问题,或者说是应用线程在哪里花了最多的时间来进入监视器,查看”线程“选项卡组的 “争用”选项卡。看看哪些锁上的竞争最多和 等待获得锁的线程的栈轨迹。如下图:
jfr-synchronization

上图的范围选择让你可以看到事件在哪里发生。在选中时间范围内放大范围选择器来查看竞争事件。

典型地,查找你不认为是问题的竞争可能是个问题。有的应用,日志是不被认为是应用瓶颈的常见区域。

当你程序更新或应用的任何时间看到性能退化,在事情还好的情况下获得一个记录,在事情看起来不好时获取另一个记录(,做对比)。

注意:在范围选择器里显示的事件不是所有的同步事件。默认地,竞争事件的持续时间超过 20 ms 才会被记录(这个阀值在开启记录时可以修改)。缩短这个阀值会得到更多的事件,也潜在地带来更多的开销。如果你认为竞争是个问题,你可以缩短记录的时间,设置很小的阀值(仅仅几毫秒)。当这些在存活应用上完成时,确保记录时间很短并监视性能开销。

五、I/O 性能

当 Java 应用花了大量时间在读写套接字或文件上时,那么 I/O 或网络可能是瓶颈。
jfr-io

上图显示了应用有 100 个对远程地址 198.51.100.0 的读操作。读取的总字节数是 356 字节,用于等待的总时间是 1 分 57 秒。选择左上角的 “By Event” 选项卡查看每个事件来分析花费的时间和读取的数据。

文件或网络 I/O 问题的诊断用同样的方式。

在 I/O 里的所有选项卡默认显示持续时间超过 20ms 的事件,可以在启动时调整阀值。

六、代码执行性能

当没有很多 Java 应用事件时,主要的瓶颈可能在你的应用运行代码上。首先,在“the Threads”选项卡选择“Overview”选项卡,看 “CPU Usage Over Time”。这显示了记录下的 JVM CPU 使用情况和机器的总的 CPU 使用情况。如果 JVM CPU 使用低,但机器的 CPU 使用高,这意味着其他应用占用了很多 CPU。然后在“System”选项卡组的“Processes”选项卡查看系统里其他应用。然而,你可能看不到它们的 CPU 使用情况,所以,通常用 OS 的工具如 top 或任务管理器来找出使用了很多 CPU 的进程。

选择“Code”选项卡组,查看“Hot Threads”选项卡以防你的应用使用了很多 CPU 时间。这个选项卡显示了使用 CPU 时间最多的线程。然而,这个信息是基于方法抽样的,因此这可能不是百分百精确的,如果抽样数量低。当 JFR 运行时,JVM 抽样线程。默认地,一个持续记录只进行方法抽样,而一个性能记录会尽可能多做。方法抽样只收集实际运行代码的线程的数据。这些等待 I/O、睡眠、等待锁等是不会被抽样的。因此,因此,有很多方法抽样的线程是使用 CPU 时间最多的;然而,每个线程使用了多少 CPU 是不知的。

“Code”选项卡组里的“Hot Methods”选项卡帮助找出应用在哪里花了最多的执行时间。这个选项卡显示了栈里按顶层方法分组的抽样。用“Call Tree”选项卡,从栈轨迹的最低端方法开始,然后向上。
jfr-stack-trace

相关 [java flight recordings] 推荐:

Java Flight Recordings (JFR) — part 2 用 JFR 定位性能问题

- - 码蜂笔记
对于有些应用,瓶颈可能是等待 I/O 或网络,可能是线程之间的同步,或者是实际的 CPU 使用. 对于其他,瓶颈可能是 GC 时间. 找出应用瓶颈的一个方法是查看 Events 选项卡. 这是一个高级选项卡,可以做不少事情. 如下图,可以选择自己感兴趣的事件:. 在“Graph”选项卡里,每一行是一个线程,每个线程可以有多行.

Twitter发布基于组件的轻量级JavaScript框架——Flight

- - InfoQ cn
前不久,Twitter发布了Flight项目. Flight是一个轻量级的、基于组件的JavaScript框架,可以将行为映射到DOM节点上. Twitter将其用在自己的Web应用上. Flight团队这样解释为什么要开发Flight:. Flight与其他现有框架的不同之处在于:对于web应用,它不会预先规定或提供任何特定呈现或提供数据的方法.

Google Flight Search 上线,暂时仅限搜索美国境内航班

- 正宗 - 谷奥——探寻谷歌的奥秘
继酒店搜索之后,Google Flight Search航班搜索终于来了,这也是Google收购ITA之后的成果展示. 你可以通过搜索flights from xxx to xxx在搜索结果的侧边栏里选择Flight进入专门的Google Flight Search,也可以进入Google Flight Search之后再选择起飞和降落地点.

Java中的锁(Locks in Java)

- - 并发编程网 - ifeve.com
原文链接 作者:Jakob Jenkov 译者:申章 校对:丁一. 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂. 因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字( 译者注:这说的是Java 5之前的情况).

Java PaaS 对决

- 呆瓜 - IBM developerWorks 中国 : 文档库
本文为 Java 开发人员比较了三种主要的 Platform as a Service (PaaS) 产品:Google App Engine for Java、Amazon Elastic Beanstalk 和 CloudBees RUN@Cloud. 它分析了每种服务独特的技术方法、优点以及缺点,而且还讨论了常见的解决方法.

Java浮点数

- d0ngd0ng - 译言-电脑/网络/数码科技
Thomas Wang, 2000年3月. Java浮点数的定义大体上遵守了二进制浮点运算标准(即IEEE 754标准). IEEE 754标准提供了浮点数无穷,负无穷,负零和非数字(Not a number,简称NaN)的定义. 在Java开发方面,这些东西经常被多数程序员混淆. 在本文中,我们将讨论计算这些特殊的浮点数相关的结果.

Qt——转战Java?

- - 博客 - 伯乐在线
编者按:事实上,在跨平台开发方面,Qt仍是最好的工具之一,无可厚非,但Qt目前没有得到任何主流移动操作系统的正式支持. 诺基亚的未来计划,定位非常模糊,这也是令很多第三方开发者感到失望,因此将导致诺基亚屡遭失败的原因. Qt的主要开发者之一Mirko Boehm在博客上强烈讽刺Nokia裁了Qt部门的决定,称其为“绝望之举”,而非“策略变更”.

java 验证码

- - ITeye博客
// 创建字体,字体的大小应该根据图片的高度来定. // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到. // randomCode用于保存随机产生的验证码,以便用户登录后进行验证. // 随机产生codeCount数字的验证码. // 得到随机产生的验证码数字. // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同.

Java异常

- - CSDN博客推荐文章
“好的程序设计语言能够帮助程序员写出好程序,但是无论哪种语言都避免不了程序员写出坏的程序.                                                                                                                          ----《Java编程思想》.

java面试题

- - Java - 编程语言 - ITeye博客
 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面. 抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节. 抽象包括两个方面,一是过程抽象,二是数据抽象.  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法. 对象的一个新类可以从现有的类中派生,这个过程称为类继承.