假设我正在测试一个 Java 服务器应用程序。我知道完成考试需要多少时间。现在我想知道在那次测试期间在 GC 上花了多少钱。我该怎么做?
7 回答
我猜当 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;
}
最简单的方法是在启动 JVM 时使用-Xloggc
和选项。-XX:-PrintGCTimeStamps
我认为它会打印出垃圾收集需要多长时间。
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
此性能指标由 JVM 记录,并可通过 JMX 访问。对于交互式监控,使用 JConsole 连接到正在运行的 JVM,然后在“VM Summary”选项卡中会显示如下内容:
垃圾收集器:名称 = 'Copy',集合 = 26,总时间花费 = 0.183 秒垃圾收集器:名称 = 'MarkSweepCompact',集合 = 2,总时间花费 = 0.168 秒
您还可以以编程方式查询 JMX。
另一个方便的解决方案是在测试完成后针对您的流程运行jstat -gc
(文档)。这将为您提供关于在 JVM 的生命周期中在 GC 中花费了多少时间的汇总输出。
有不同的 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 秒]
类似于使用ManagementFactory的@Steve McLeod 的答案,因为 Java 8 这也可以使用Java 流在一行中编写:
long collectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();