Java 测量JVM中GC花费的时间
假设我正在测试一个Java服务器应用程序。我知道完成考试要花多少时间。现在我想知道在那个测试中,GC花费了多少钱。我怎么做 最简单的方法是在启动JVM时使用Java 测量JVM中GC花费的时间,java,performance,garbage-collection,jvm,qa,Java,Performance,Garbage Collection,Jvm,Qa,假设我正在测试一个Java服务器应用程序。我知道完成考试要花多少时间。现在我想知道在那个测试中,GC花费了多少钱。我怎么做 最简单的方法是在启动JVM时使用-Xloggc和-XX:-printgcmtimestamps选项。我想它会打印出垃圾收集所需的时间 我猜当GC(垃圾收集器)工作时,应用程序停止,并在GC完成时恢复 我认为这不是一个安全的假设。您确定垃圾收集器没有与应用程序代码并行工作吗 要测量收集垃圾花费的时间,可以查询 试试这个: public static void main(St
-Xloggc
和-XX:-printgcmtimestamps
选项。我想它会打印出垃圾收集所需的时间
我猜当GC(垃圾收集器)工作时,应用程序停止,并在GC完成时恢复
我认为这不是一个安全的假设。您确定垃圾收集器没有与应用程序代码并行工作吗
要测量收集垃圾花费的时间,可以查询
试试这个:
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;
}
启用垃圾收集日志。同样,您可以使用
-verbose:gc
,-XX:+PrintGCDetails
和-XX:+PrintGCTimeStamps
标志-Xloggc
标志可用于将这些文件定向到文件
结果日志是人类可读的,但为了最大的好处,您可能希望它们通过分析器运行。这些工具列在中。此性能指标由JVM记录,并可通过JMX访问。对于交互式监视,使用JConsole连接到正在运行的JVM,并在“VM摘要”选项卡中显示如下内容: 垃圾收集器:名称='Copy',收集=26,总花费时间=0.183秒 垃圾收集器:Name='MarkSweepCompact',Collections=2,总花费时间=0.168秒
您还可以通过编程方式查询JMX。有不同的GC算法,它们的行为不同。我最近读了一篇关于这个主题的文章,如果你想知道更多的话,我可以向你推荐 您可以使用以下命令行选项启动应用程序
-verbose:gc-XX:+printgcdatastamps-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秒]
另一个方便的解决方案是在测试完成后对流程运行
jstat-gc
()。这将为您提供关于JVM生命周期内GC花费了多少时间的良好聚合输出。类似于@Steve McLeod使用的答案,因为Java 8也可以使用以下命令在一行中编写:
我计算了在测试中端到端运行的时间,包括GC时间,并且我只在我想对它进行性能调优时(例如使用内存分析器)才分解它。这个答案非常好。我已经在GC上执行了许多测试,
GarbageCollectorMXBean
提供的值与JVM参数编写的日志完全相同。getGarbageCollectorMXBeans()
何时返回多个MXBean?getGarbageCollectorMXBeans()何时返回
返回多个mx bean?我目前无法测试它,但我非常确定,如果两个不同的收集器分别用于次要和主要收集,就会出现这种情况。
long collectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();