Java飞行记录器

JFR和JMC

JFR全称为Java Flight Recorder,即Java飞行记录器
JMC全称为JDK Mission Control,即JDK任务控制
先贴一段官网的简介:

Java Flight Recorder and JDK Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis.
Java飞行记录器和JDK任务控制一起创建了一个完整的工具链,以持续收集低级别和详细的运行时信息,从而支持事后事件分析。

Java Flight Recorder is a profiling and event collection framework built into the Oracle JDK.
It allows Java administrators and developers to gather detailed low level information about how the Java Virtual Machine (JVM) and the Java application are behaving.
Java飞行记录器是一个内置在Oracle JDK中的分析和事件收集框架。
它允许Java管理员和开发人员收集关于Java虚拟机(JVM)和Java应用程序如何行为的详细底层信息。

JDK Mission Control (JMC) is a production-time profiling and diagnostics tool.
It includes tools to monitor and manage your Java application with a very small performance overhead, and is suitable for monitoring applications running in production.
JDK Mission Control is an advanced set of tools that enables efficient and detailed analysis of the extensive of data collected by Java Flight Recorder.
The tool chain enables developers and administrators to collect and analyze data from Java applications running locally or deployed in production environments.
JDK任务控制(JMC)是一个生产时间分析和诊断工具。
它包括用于监控和管理Java应用程序的工具,并且适用于监控在生产中运行的应用程序。
JDK任务控制是一套先进的工具,能够对Java飞行记录器收集的大量数据进行高效和详细的分析。
该工具链使开发人员和管理员能够从本地运行或部署在生产环境中的Java应用程序中收集和分析数据。

可见,JFR用来记录和收集Java运行时的数据和事件;JMC是分析和诊断工具,可用来打开和分析JFR文件

启动飞行记录

  1. 官网下载JMC8.3.1
  2. 启动一个Java程序
  3. 打开jmc.exe,选择一个Java程序->右键->启动飞行记录
    在这里插入图片描述
    可选择记录时间,默认是1分钟
    在这里插入图片描述
    可以看到正在记录,并有倒计时
    在这里插入图片描述
  4. 记录完成后,会生成.jfr后缀文件,可用JMC打开

用JFR对比不同GC器

代码如下:

public class Test {
    public static void main(String[] args) {
        // 记录线程编号
        AtomicInteger threadNo = new AtomicInteger(1);
        // 主线程池
        ScheduledExecutorService gcExecutor = Executors.newScheduledThreadPool(5);
        // 监控主线程池的线程池,用来停止主线程池
        ExecutorService monitorExecutor = Executors.newSingleThreadExecutor();
        long start = System.currentTimeMillis();

        monitorExecutor.execute(() -> {
            // 主线程池运行70秒
            while (System.currentTimeMillis() - start < 70 * 1000) {
                try {
                    TimeUnit.MILLISECONDS.sleep(100L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            // 停止主线程池
            gcExecutor.shutdownNow();
        });
        monitorExecutor.shutdown();

        for (int i = 0; i < 1_000_000; i++) {
            gcExecutor.execute(() -> {
                Thread.currentThread().setName("-gc-thread-" + threadNo.getAndIncrement());
                System.out.println(Thread.currentThread().getName() + "\tstart");
                // 疯狂创建对象,触发GC
                for (int k = 0; k < 1_000_000; k++) {
                    if (gcExecutor.isTerminated()) {
                        return;
                    }
                    new GcObj(k);
                }
                System.out.println(Thread.currentThread().getName() + "\tfinish");
            });
        }

        while (!gcExecutor.isTerminated()) {
        }
        System.out.println(System.currentTimeMillis() - start + "ms");
    }

    @AllArgsConstructor
    private static class GcObj {
        private final int i;
    }
}

分别用下面3种组合运行程序,启动飞行记录:

  • JDK:1.8.0_371,GC:CMS
  • JDK:17.0.7,GC:G1,-XX:+UseG1GC
  • JDK:17.0.7,GC:ZGC,-XX:+UseZGC

运行结果

在这里插入图片描述
可见,CMS在70秒内只处理了3W+个线程,而G1和ZGC则可以处理56W+个线程,CMS在GC的STW上消耗了大量时间

记录结果

GC配置

在这里插入图片描述

GC Summary

在这里插入图片描述
可见,CMS的GC时间=STW时间,G1和ZGC的STW时间远小于GC时间,也验证了存在与应用程序并行的GC阶段,效率大大提高

垃圾收集

在这里插入图片描述
Allocation Failure
Ergonomics
G1 Evacuation Pause
G1 Humongous Allocation
Warmup

作者:曼特宁

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值