【问题标题】:Can you get basic GC stats in Java?你能在 Java 中获得基本的 GC 统计信息吗?
【发布时间】:2021-11-03 03:16:20
【问题描述】:

我想让一些长时间运行的服务器应用程序定期输出 Java 中的一般 GC 性能数字,比如 Runtime.freeMemory() 等 GC 等价物。比如完成的周期数、平均时间等。

我们的系统在客户机器上运行,怀疑配置错误的内存池会导致过多的 GC 频率和长度 - 我认为定期报告基本 GC 活动通常是好的。

是否有任何独立于平台的方式来做到这一点?

编辑:我特别想在运行时将此数据输出到系统日志(控制台);这不是我想连接到 JVM 的东西,就像 JConsole 或 JVisualVM 一样。

Edit2:MX bean 看起来像我想要的 - 有没有人有一个获得其中之一的工作代码示例?

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

    这是一个使用 @987654321@ 打印 GC 统计信息的示例。大概您会定期调用此方法,例如使用@987654322@ 进行调度。

    public void printGCStats() {
        long totalGarbageCollections = 0;
        long garbageCollectionTime = 0;
    
        for(GarbageCollectorMXBean gc :
                ManagementFactory.getGarbageCollectorMXBeans()) {
    
            long count = gc.getCollectionCount();
    
            if(count >= 0) {
                totalGarbageCollections += count;
            }
    
            long time = gc.getCollectionTime();
    
            if(time >= 0) {
                garbageCollectionTime += time;
            }
        }
    
        System.out.println("Total Garbage Collections: "
            + totalGarbageCollections);
        System.out.println("Total Garbage Collection Time (ms): "
            + garbageCollectionTime);
    }
    

    【讨论】:

    • 非常感谢 Greg。我已经有一个定期监视器,可以打印内存使用情况和可选的线程。这很适合。
    • PS:不能再投票46分钟;届时将返回并对此进行投票。
    • getCollectionCount() 是返回自上次调用以来的计数,还是总计数?
    • 测试显示getCollectionCount() 返回的计数是自它开始以来的总计数,因此此示例中的累加器将报告比实际发生的总计数要高得多。
    • @MikeRylander 示例代码中的累加器旨在跨多个 GarbageCollectorMXBean 实例进行累加,而不是对同一实例的多次调用。请注意,累加器变量的作用域是方法而不是静态的。
    【解决方案2】:

    【讨论】:

    • 谢谢,顺便说一句,冉;如果我能接受两个答案,我也会接受这个。
    【解决方案3】:

    JVM 已内置一定数量的垃圾收集器日志记录,因此根据您的要求,您可能不需要自定义解决方案。

    在 Java 7 中,您可以使用 -XX:-PrintGC-XX:-PrintGCDetails;见VM Debugging Options

    在 Java 8 到 10 中,将 -XX:+PrintGC-XX:+PrintGCDetails+ 一起使用,而不是 - (source)。

    在 Java 11 或更高版本中,-XX 选项 have been deprecated 支持 -Xlog:gc。有关更多高级选项,请参阅 Enabling Logging with the JVM Unified Logging Framework

    【讨论】:

    • 好主意;但过于冗长,无法始终开启。我想要一份定期报告,比如每 5-60 分钟一次。
    • 那么我认为您必须编写其他内容来捕获输出并在您的时间重新格式化/重新输出。
    • 实际上这对我有用:-XX:+PrintGC 和 -XX:+PrintGCDetails(带 + 号)
    【解决方案4】:

    有点离题,但您可以将 VisualVM 和 JConsole 连接到正在运行的应用程序并查看有用的统计信息。

    【讨论】:

    • 请参阅我在发布此答案 13 小时前写的粗体编辑。
    • 对此深表歉意 - 有时您只见树木不见森林。
    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2022-07-07
    • 2021-12-23
    • 2012-02-22
    • 2015-12-25
    相关资源
    最近更新 更多