假设我正在测试Java服务器应用程序。我知道完成测试需要多长时间。现在,我想知道在测试期间在GC上花了多少钱。我该怎么做?
答案 0 :(得分:22)
我想当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;
}
答案 1 :(得分:6)
最简单的方法是在启动JVM时使用-Xloggc
和-XX:-PrintGCTimeStamps
选项。我认为它打印出垃圾收集需要多长时间。
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
答案 2 :(得分:3)
此性能指标由JVM记录,并可通过JMX访问。对于交互式监视,使用JConsole连接到正在运行的JVM,在“VM Summary”选项卡中,它将显示如下内容:
垃圾收集器:Name ='Copy',Collections = 26,花费的总时间= 0.183秒 垃圾收集器:Name ='MarkSweepCompact',Collections = 2,花费的总时间= 0.168秒
您也可以以编程方式查询JMX。
答案 3 :(得分:3)
另一个方便的解决方案是在测试完成后针对您的流程运行jstat -gc
(documentation)。这将为您提供很好的聚合输出,确切地说明在JVM的生命周期中GC花费了多少时间。
答案 4 :(得分:1)
启用垃圾回收日志。如documented,您可以使用-verbose:gc
,-XX:+PrintGCDetails
和-XX:+PrintGCTimeStamps
标记。 -Xloggc
标志可用于将这些标志指向文件。
生成的日志是人类可读的,但是对于大多数好处,您可能希望它们通过分析器运行。这些工具列在this thread。
中答案 5 :(得分:1)
有不同的GC算法表现不同。我最近读了一篇关于这个主题的good article,如果你想了解更多,我可以推荐。
您可以使用以下命令行选项-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 sys = 0.01, 真实= 0.58秒]
答案 6 :(得分:1)
类似于@Steve McLeod使用ManagementFactory的答案,因为Java 8也可以使用Java streams在一行中编写:
long collectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();