诸如“不可持续的分配率”和“您需要保持较低的分配率”等短语似乎仅属于Java Champions的词汇表。 复杂,恐怖并被魔术光环包围。
经常发生的情况是,当您更仔细地查看概念时,魔术会随着抽烟消失。 这篇文章试图从提到的条款中删除魔术。
什么是分配率?我为什么要关心?
分配率以每个时间单位分配的内存量来衡量。 通常以MB /秒表示,但如果您愿意,可以每年使用PB。 这就是全部,没有魔术,只是您在一段时间内在Java代码中分配的内存量。
但是,仅了解这一事实并不太有益。 如果您可以忍受我,我将指导您实际使用该概念。
面对高分配率可能会给您的应用程序性能带来麻烦。 从实际的角度来看, 垃圾收集已成为瓶颈,从而浮出水面。 从硬件的角度来看,即使是商用硬件,每个内核也可以维持数GB /秒的分配,因此,如果您的速率开始不超过1 GB /秒/核,您可以放心,您的硬件实际上不会成为瓶颈。
因此,在关注GC时,我们可以从一个在现实世界中也适用的类比开始-如果您创建很多东西,那么之后往往会面临很多清理工作。 知道JVM是使用垃圾收集机制构建的,因此需要研究分配速率如何更改GC暂停的频率或持续时间。
衡量分配率
让我们从分配率的测量开始。 为此,我们通过为JVM指定-XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps标志来打开GC日志记录。 JVM现在以与以下代码段类似的方式开始记录GC暂停:
0.291: [GC (Allocation Failure) [PSYoungGen: 33280K->5088K(38400K)] 33280K->24360K(125952K), 0.0365286 secs] [Times: user=0.11 sys=0.02, real=0.04 secs]
0.446: [GC (Allocation Failure) [PSYoungGen: 38368K->5120K(71680K)] 57640K->46240K(159232K), 0.0456796 secs] [Times: user=0.15 sys=0.02, real=0.04 secs]
0.829: [GC (Allocation Failure) [PSYoungGen: 71680K->5120K(71680K)] 112800K->81912K(159232K), 0.0861795 secs] [Times: user=0.23 sys=0.03, real=0.09 secs]
从上面的GC日志中, 我们可以将分配率计算为上一个收集完成后和下一个收集开始之前的年轻代大小之间的差。 使用上面的示例,我们可以例如提取以下信息:
- JVM启动后的291 ms ,创建了33,280K 个对象。 第一次小型GC事件清除了Young一代,此后,Young一代还剩下5,088K个对象。
- 发射后446毫秒,Young gen占用已增加到38,368 K, 触发了下一个GC,从而将Young Gen的占用减少到了5,120K 。
- 发射后829毫秒,Young gen大小为71,680K ,GC再次将其减小至5,120K 。
然后可以在下表中表示此数据,将分配率计算为年轻入住率的增量:
事件 | 时间 | 年轻之前 | 年轻之后 | 分配期间 | 分配率 |
---|---|---|---|---|---|
第一GC | 291ms | 33,280KB | 5,088KB | 33,280KB | 114MB /秒 |
第二GC | 446毫秒 | 38,368KB | 5,120KB | 33,280KB | 215MB /秒 |
第三GC | 829毫秒 | 71,680KB | 5,120KB | 66,560KB | 174MB /秒 |
总 | 829毫秒 | 不适用 | 不适用 | 133,120KB | 161MB /秒 |
有了这些信息,我们可以说该特定软件在测量期间的分配速率为161 MB /秒。
分析影响
现在,有了这些信息,我们就可以了解分配速率的变化如何通过增加或减少GC暂停的频率来影响应用程序吞吐量。 首先,您应该注意到只有Minor GC暂停清洁Young Generation会受到影响。 GC清理旧一代的频率或持续时间不受分配率的直接影响,而受晋升率的直接影响, 晋升率将在下一篇文章中介绍。
知道我们只能专注于次要GC暂停时,我们接下来应该研究Young Generation内部的不同内存池。 当分配在Eden中进行时 ,我们可以立即查看Eden的大小如何影响分配率。 因此,我们可以有一个假设,即增加Eden的大小将减少较小的GC暂停频率,从而使应用程序能够维持更快的分配速率。
实际上,当使用-XX:NewSize -XX:MaxNewSize和-XX:SurvivorRatio参数运行具有不同Eden大小的相同示例时,我们可以看到分配率有两倍的差异
- 以100M的Eden运行上述示例,将分配速率降低到100MB / sec以下
- 将Eden大小增加到1GB,可以将分配速率增加到刚好低于200MB /秒。
如果您仍然想知道为什么这是正确的- 如果您不常停止GC的应用程序线程,则可以做更多有用的工作。 还发生了更多有用的工作来创建更多对象,从而支持增加的分配率 。
现在,在得出“更大的伊甸园更好”的结论之前,您应该注意到分配率可能并且可能与应用程序的实际吞吐量没有直接关系。 这是一项技术指标,有助于提高吞吐量。 分配速率可能会并且会影响您的次要GC暂停停止应用程序线程的频率,但是要查看整体影响,您还需要考虑主要GC暂停并以应用程序的业务操作(不是MB / sec)来衡量吞吐量。提供。
翻译自: https://www.javacodegeeks.com/2015/09/what-is-allocation-rate.html