Java Flight Record 详解

5 篇文章 0 订阅

核心概念

Java Flight Record 提供一个低开销的数据收集框架,用于对 Java 应用程序和 HotSpot JVM 进行故障排除。Flight Recorder 记录源自应用程序JVM操作系统事件

Flight Record,顾名思义,相当于飞机黑匣子里保存的飞行记录

事件

JFR在Java应用运行时收集对应发生的事件,主要有三种类型的事件提供给JFR收集:

  • 即时事件:一旦事件发生会立即进行数据记录
  • 持续事件:如果持续时间超过指定阈值则进行数据记录
  • 简单事件:用于记录应用所在系统的活跃指标(例如CPU,内存等)

Java Flight Recorder (JFR) 可以监听和记录各种事件,包括但不限于以下几类:

  1. 方法耗时:JFR 可以记录方法的执行时间,用于分析和优化程序的性能。
  2. 垃圾收集:JFR 可以记录垃圾收集器的活动和性能指标,包括吞吐量、停顿时间和对象分配等。
  3. 线程活动:JFR 可以记录线程的创建、销毁、休眠和唤醒等活动,用于分析并发和线程相关的性能问题。
  4. 锁竞争:JFR 可以记录锁的竞争和等待情况,用于分析多线程程序中的死锁和竞争问题。
  5. I/O 操作:JFR 可以记录文件读写、网络传输等 I/O 操作的性能指标和耗时,用于分析和优化 I/O 性能。
  6. GC 周期:JFR 可以记录整个 GC 周期的信息,包括新生代、老年代和永久代的使用情况和回收效率等。
  7. 内存分配:JFR 可以记录内存的分配和使用情况,包括堆内、堆外和直接内存的分配和释放情况。

除了上述事件,JFR 还支持自定义事件,您可以根据应用程序的需求自定义记录特定事件和指标。这些事件和指标可以帮助开发人员了解应用程序的行为和性能状况,并进行性能优化和故障排查。

缓冲机制和二进制数据格式

线程将事件无锁地写入ThreadLocal缓冲区。一旦ThreadLocal缓冲区填满,它就会被提升为全局内存循环缓冲区系统,该系统维护最新的事件数据。根据配置,最旧的数据要么被丢弃,要么被写入磁盘,从而允许连续保存历史记录

事件模型以little endian base 128的形式编码的二进制格式实现。磁盘上的二进制文件具有扩展名.jfr,并使用保留策略进行维护和控制

作为说明性示例,类加载事件包含描述其发生时间的时间戳、描述时间跨度的持续时间、线程、堆栈跟踪以及三个事件特定有效负载字段、加载的类和关联的类加载器。事件的大小总共为 24 字节。

<memory address>: 98 80 80 00 87 02 95 ae e4 b2 92 03 a2 f7 ae 9a 94 02 02 01 8d 11 00 00
  • 活动规模[98 80 80 00]
  • 事件ID[87 02]
  • 时间戳[95 ae e4 b2 92 03]
  • 期间[a2 f7 ae 9a 94 02]
  • 线程ID[02]
  • 堆栈跟踪 ID[01]
  • 有效负载[字段]
    • 加载类:[0x8d11]
    • 定义类加载器:[0]
    • 启动类加载器:[0]

JFR 诊断

在 JVM 命令启动JFR

-XX:StartFlightRecording

bin/jcmd 工具启动JFR

# 启动JFR
jcmd <pid> JFR.start

# dump
jcmd <pid> JFR.dump filename=recording.jfr

# 停止JFR
jcmd <pid> JFR.stop

命令参数详见 JFR命令参考

JFR 解析

输出jfr文件后,可以使用JDK Mission Control分析工具对各种性能指标进行分析。可以直接使用JFR 解析命令查看摘要信息和事件流

JDK Mission Control

JDK Mission Control是一个强大的性能分析工具,它包含了对JFR文件进行可视化分析的功能。可以使用JDK Mission Control打开JFR文件,查看各种性能指标、方法调用树、线程活动等信息,并进行高级分析和故障排查。

JFR 解析命令

jfr print <filename.jfr>

部分JFR文件的摘要信息和事件流

jdk.CodeCacheStatistics {
  startTime = 16:13:08.344
  codeBlobType = "CodeHeap 'non-nmethods'"
  startAddress = 0x7FE6A1715000
  reservedTopAddress = 0x7FE6A1CA4000
  entryCount = 1134
  methodCount = 0
  adaptorCount = 1046
  unallocatedCapacity = 3.7 MB
  fullCount = 0
}

jdk.CodeSweeperStatistics {
  startTime = 16:13:08.344
  sweepCount = 72
  methodReclaimedCount = 11991
  totalSweepTime = 3.09 s
  peakFractionTime = 208 ms
  peakSweepTime = 208 ms
}

jdk.GCConfiguration {
  startTime = 16:13:08.344
  youngCollector = "N/A"
  oldCollector = "Z"
  parallelGCThreads = 2
  concurrentGCThreads = 1
  usesDynamicGCThreads = true
  isExplicitGCConcurrent = false
  isExplicitGCDisabled = true
  pauseTarget = N/A
  gcTimeRatio = 99
}

使用实例

自动分析结果

自动分析结果

JMC分析

JMC分析

事件浏览器

事件浏览器

HotSpot JVM 中的对象指针压缩

总结

  1. 低开销的性能监控:JFR 是与 JVM 集成的轻量级性能监控工具,可以在不影响应用程序性能的情况下实时收集和记录各种性能数据。与其他性能工具相比,JFR 的性能开销非常低,几乎可以忽略不计
  2. 实时和历史数据记录:使用 JFR,您可以实时记录应用程序的性能数据,例如线程活动、方法执行时间、垃圾收集等。您还可以通过配置持久化设置,将记录的数据保存为 JFR 文件,以供后续分析和排查问题
  3. 低停顿垃圾收集(Low-Pause Garbage Collection):JFR 可以捕获 Java 垃圾收集器的详细信息,包括停顿时间、吞吐量、对象分配等。这些数据可以帮助您了解垃圾收集器的性能特征并进行优化
  4. 生产环境监控:使用 JFR,您可以在生产环境中实时监控应用程序的性能和健康状况。通过收集关键指标,您可以及时发现和解决潜在的问题,避免应用程序性能下降或故障
  5. 高度可定制性:JFR 提供了丰富的配置选项,可以根据您的需求定制性能监控的粒度和数据采集。您可以选择感兴趣的事件、添加自定义事件和属性,以满足您特定的监控需求
  6. 集成与分析工具:JFR 数据可以与 JDK Mission Control 等工具集成,提供直观的可视化界面和高级分析功能。开发人员可以使用这些工具快速定位性能问题,并进行优化

总而言之,Java JFR是一个功能强大且易于使用的性能监控和故障诊断工具,可以帮助开发人员优化Java应用程序的性能,并提高应用程序在生产环境中的稳定性


参考资料:

  1. JEP 328: Flight Recorder
  2. Java Platform, Standard Edition Java Flight Recorder Runtime Guide
  3. JFR-Java Flight Record
  4. JEP 167:基于事件的 JVM 跟踪
  5. JDK Mission Control
  6. 深度探索JFR - JFR详细介绍与生产问题定位落地
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的Flight类通常用于表示航班信息。这个类可以包含航班号、出发地、目的地、起飞时间、到达时间等信息。在实际应用中,我们可以使用Flight类来管理航班的信息,比如查询航班信息、预订机票、取消航班等。 下面是一个简单的Flight类的示例: ``` public class Flight { private String flightNumber; private String departure; private String destination; private String departureTime; private String arrivalTime; public Flight(String flightNumber, String departure, String destination, String departureTime, String arrivalTime) { this.flightNumber = flightNumber; this.departure = departure; this.destination = destination; this.departureTime = departureTime; this.arrivalTime = arrivalTime; } // getters and setters public String getFlightNumber() { return flightNumber; } public void setFlightNumber(String flightNumber) { this.flightNumber = flightNumber; } public String getDeparture() { return departure; } public void setDeparture(String departure) { this.departure = departure; } public String getDestination() { return destination; } public void setDestination(String destination) { this.destination = destination; } public String getDepartureTime() { return departureTime; } public void setDepartureTime(String departureTime) { this.departureTime = departureTime; } public String getArrivalTime() { return arrivalTime; } public void setArrivalTime(String arrivalTime) { this.arrivalTime = arrivalTime; } } ``` 在这个示例中,Flight类包含了航班号、出发地、目的地、起飞时间、到达时间等信息,并提供了相应的getter和setter方法来获取和设置这些信息。可以根据实际需要对Flight类进行扩展,比如添加舱位信息、票价信息等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值