在Java服务器中计算GC时间的百分比

10

我正在使用 jstat 来获取GC操作的总累计时间,即 GCT

因此,假设GCT为2秒,我的JVM进程已经运行了60秒,我在四核服务器上运行,所以我的GC百分比是多少?

2 / 60 * 4 = 0.83%

以上的计算是否正确?

4个回答

6
不,你的计算并不精确,因为这样,你不知道操作系统允许你的程序运行的确切时间。
假设你想考虑应用程序被垃圾回收器完全停止的时间(暂停时间),你可以使用以下JVM选项:
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCApplicationStoppedTime

这个选项将使JVM将类似以下内容打印到标准输出(stdout):
Application time: 3.3319318 seconds
Total time for which application threads were stopped: 0.7876304 seconds
Application time: 2.1039898 seconds
Total time for which application threads were stopped: 0.4100732 seconds

你可以将应用程序停止的时间总和除以应用程序时间加暂停时间的总和,以获得变异器利用率(应用程序未被GC暂停的时间分数)。
另请参阅http://prefetch.net/blog/index.php/2008/02/18/measuring-the-time-an-application-was-stopped-due-to-garbage-collection/

1
你知道这些参数的文档在哪里吗?应用程序时间是墙上时间还是CPU时间? - radai
@radai 很好的问题 - 我不是很确定,但我会尝试找出答案并更新回答。 - Michael Schmeißer

3

不,实际上并不是这样的。您的计算假定java进程在整个时间内对所有4个核心的利用率达到了100%。

正确的计算方法是(逻辑处理所花费的时间) / (垃圾回收所花费的时间),但通常需要使用分析器来获取第一个信息片段。


这很有道理,但是使用jstat或其他工具检索“逻辑时间花费”的值是否可能?谢谢。 - Ryan

1
不,这个计算是不正确的。你想要计算的是:
( CPU spent on GC ) / ( total CPU spent on JVM)

正如其他评论所指出的那样,“JVM上总CPU使用时间”将低于60*4,因为这假定您的应用程序完全加载系统,并且操作系统或其他应用程序没有使用CPU周期。在Linux上,可以使用“time”和“ps”命令来找到正确的数字。
然而,“GC上花费的CPU时间”也很难通过jstat命令找到。我怀疑jstat报告的是墙钟时间(而不是CPU时间),这对于上面的计算是无用的--再次强调,您不知道GC是否在墙钟时间段内完全加载了所有核心。令人惊讶的是,关于jstat命令报告的是哪种时间(墙钟时间还是CPU时间)的清晰文档并不存在--如果我错过了,请在此处留下评论。

1

打印GCDetails - 这个选项可能会很有帮助。它会打印每次垃圾回收的信息。

[GC
[PSYoungGen: 99952K->14688K(109312K)]
422212K->341136K(764672K), 0.0631991 secs]
[Times: user=0.83 sys=0.00, real=0.06 secs]

提供CPU使用率和已用时间信息。user右侧的值是垃圾收集执行操作系统外指令所使用的CPU时间。例如,在此示例中,垃圾收集器使用了0.06秒的用户CPU时间。sys右侧的值是操作系统代表垃圾收集器使用的CPU时间。例如,在此示例中,垃圾收集器未使用任何CPU时间代表垃圾收集器执行操作系统指令。real右侧的值是垃圾收集的经过秒数的流逝的挂钟时间。例如,在此示例中,完成垃圾收集需要0.06秒。 Java Performance-好书,可以在数字版本中找到。包含有关测量GC影响的重要文章。

谢谢,我正在使用PrintGCDetails,但它只告诉我垃圾回收时间,我想知道百分比以进行比较。 - Ryan
这是一个非常奇怪的目的,说实话。为什么不通过调整垃圾回收类型和代数大小来最小化相同测试用例的GC时间呢? - Mikhail

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接