16

假设我正在测试一个 Java 服务器应用程序。我知道完成考试需要多少时间。现在我想知道在那次测试期间在 GC 上花了多少钱。我该怎么做?

4

7 回答 7

25

我猜当 GC(垃圾收集器)工作时,应用程序停止并在 GC 完成时恢复

我不认为这是一个安全的假设。您确定垃圾收集器没有与您的应用程序代码并行工作吗?

要测量收集垃圾所花费的时间,您可以查询Garbage Collector MXBean

试试这个:

public static void main(String[] args)  {
    System.out.println("collectionTime = " + getGarbageCollectionTime());
}

private static long getGarbageCollectionTime() {
    long collectionTime = 0;
    for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
        collectionTime += garbageCollectorMXBean.getCollectionTime();
    }
    return collectionTime;
}
于 2012-12-17T13:50:31.953 回答
7

最简单的方法是在启动 JVM 时使用-Xloggc和选项。-XX:-PrintGCTimeStamps我认为它会打印出垃圾收集需要多长时间。

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

于 2012-12-17T13:50:04.177 回答
4

此性能指标由 JVM 记录,并可通过 JMX 访问。对于交互式监控,使用 JConsole 连接到正在运行的 JVM,然后在“VM Summary”选项卡中会显示如下内容:

垃圾收集器:名称 = 'Copy',集合 = 26,总时间花费 = 0.183 秒垃圾收集器:名称 = 'MarkSweepCompact',集合 = 2,总时间花费 = 0.168 秒

您还可以以编程方式查询 JMX。

于 2012-12-17T13:51:19.077 回答
4

另一个方便的解决方案是在测试完成后针对您的流程运行jstat -gc文档)。这将为您提供关于在 JVM 的生命周期中在 GC 中花费了多少时间的汇总输出。

于 2012-12-19T22:15:22.673 回答
1

启用垃圾收集日志。如文档所述,您可以使用-verbose:gc,-XX:+PrintGCDetails-XX:+PrintGCTimeStamps标志。-Xloggc标志可用于将它们定向到文件。

生成的日志是人类可读的,但为了获得最大利益,您可能希望它们通过分析器运行。此线程中列出了此类工具。

于 2012-12-17T13:50:58.547 回答
1

有不同的 GC 算法表现不同。我最近读了一篇关于这个主题的好文章,如果你想了解更多,我可以推荐。

您可以使用以下命令行选项启动应用程序-verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails并获取有关 GC 的信息。

这是日志消息的示例:

2012-12-17T03:02:15.590-0500: [GC [PSYoungGen: 40934K->2670K(29440K)] 48211K->14511K(73152K),0.5745260 秒] [时间:用户 = 0.08 系统 = 0.01,实际 = 0.58 秒]

于 2012-12-17T13:51:21.453 回答
1

类似于使用ManagementFactory的@Steve McLeod 的答案,因为 Java 8 这也可以使用Java 流在一行中编写:

long collectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();
于 2017-09-26T07:37:31.540 回答