JVM神秘的AllocatePrefetch选项:它们实际上是做什么的?- opsian

20-02-06 banq

AllocatePrefetch是JVM的分配预取选项。所有Java垃圾收集器都使用称为缓冲分配的技术,通过将所需的分配大小添加到当前分配指针(缓冲位),并检查该分配大小是否超出了分配指针指向的区域限制,以此来执行分配。

在并行线程分配的环境中运行时,这会带来一种复杂性。简单地让所有线程竞争使用诸如Fetch-And-Add或Compare-And-Swap之类的原子指令来分配指针将非常低效。Java垃圾收集器使用的解决此问题的方法是线程本地分配缓冲区(TLAB)。

TLAB是一个能够处理许多分配的缓冲区,并由线程拥有。线程向垃圾收集器的分配器请求这些缓冲区,然后使用它们将新对象分配到其中。由于缓冲区是线程本地的,并且缓冲区内的分配是单线程的,因此可以使用快速缓冲分配方法。JVM动态选择TLAB的大小,将较小的TLAB分配给分配很少的线程,将较大的TLAB分配给分配更频繁的线程。

现在您了解了分配的工作原理,预取从何而来?要了解预取,您首先需要了解一些有关CPU缓存的组织方式。为了保持一致的内存视图,所有缓存都位于总线上,并遵守缓存一致性协议。该协议使高速缓存可以共享数据。

在理想情况下,使用AllocatePrefetch选项,分配完全适合高速缓存行的对象时,分配性能提高了近40%。在这里,预取可确保新分配的内存位于缓存之一中,并允许存储缓冲区更快地耗尽。

如果生产环节的性能瓶颈涉及非常紧密的循环中的大量分配,则可能应该采取这种选项。接下来,确定要执行的对象分配的类型-它们的大小和相对频率。选择分配预取设置,以确保最频繁分配的对象被完全预取。最后,在生产环境中对照现有版本测试新版本。使用指标来确定性能是否有所提高。

点击标题见原文