原文

有时, 你会对你的应用程序会在GC之间执行执行多久感兴趣. 这可从GC日志中计算出来, 但一个方便的方式来查看这个信息是通过命令行选项 -XX:+PrintGCApplicationStoppedTime 以及 -XX:+PrintGCApplicationConcurrentTime . 将这些添加到你的命令行会产生这样的输出:

Application time: 0.2863875 seconds
Total time for which application threads were stopped: 0.0225087 seconds
Application time: 0.1476791 seconds
Total time for which application threads were stopped: 0.0255697 seconds

应用程序执行(在第一行报告)大约 287 ms, 然后是停止约 22 ms (第二行报告).这些选项可以单独或组合一起使用.

添加 -XX:+PrintGCTimeStamps -XX:+PrintGCDetails , 你会看到如下输出:

Application time: 0.1325032 seconds
20.149: [GC (Allocation Failure)] 
20.149: [ParNew: 78656K->8704K(78656K), 0.0221598 secs] 225454K->158894K(253440K), 0.0222106 secs] [Times: user=0.13 sys=0.00,real=0.03 secs]
Total time for which application threads were stopped: 0.0224188 seconds

当标志第一次实现 stopped 时间时确实是 GC 的停止时间, 但后来它被更改为包含完整的停止时间. 在 safepoint 期间(应用程序暂停并且虚拟机可以在不改变应用程序的情况下执行一些工作的时间段)可以完成其他工作. 所有这些都包括在 stopped 时间里. 在上面的例子中, 我会说, GC 是在 safepoint 发生的唯一事情( GC 时间为 0.0222106秒, 完成时间几乎与 0.0224188 秒相同).

由于我不知道, 我无法权威地谈论还会发生什么. 但举个例子, 我听说过编译代码去优化. 当需要抛弃 JIT 的方法代码时(通常是因为假设在编译期间出问题), VM 必须从编译代码切换到再次解释执行该方法. 这个切换是在一个 safepoint 中完成的(但不要因此引用我所说的, 因为这不是我擅长的领域).