【发布时间】:2015-09-22 21:43:51
【问题描述】:
假设我们有 1000 个相同类型的对象分散在内存中(它们是在不同时间创建的,而其他对象是在其间创建的)。
我们有一个数组,其中包含对 1000 个对象中每一个的引用。
问题
如果我们按顺序遍历数组,什么会被预取到 CPU 的缓存中?只有数组持有的引用还是这些引用会被取消引用并且对象也会被加载到缓存中?
Java(JVM)是否实现了某种软件预取?如果没有,是否有提供软件预取的库?
【问题讨论】:
-
听起来好像是特定于实现的。我也坚信这取决于软件,因为memory ordering 可能会影响这些事情。不过,最后一部分可能是错误的。
-
我很确定 CPU 缓存 100% 受硬件控制。当垃圾收集器工作时,它可能会将您的 1000 个对象合并到一个公共内存区域。然而,我读过的任何内容都没有表明任何 GC 都会这样做。无论如何,硬件缓存通常都充满了重要数据,任何“预缓存”都仅限于一个缓存行,通常约为 32-16 字节。
-
Heap分为young和old空间。young空间有最近分配的对象。当这些对象变老时,它们会转移到old区。“keep”是最近分配的地方快速移动且不会被垃圾收集的对象。
-
我认为任何 CPU 都不会预取引用。这是没有意义的,因为如果您的对象的字节大小模 64(缓存行通常为64 byte long)相对较小,您会丢失很多缓存(总体而言,这可能会减慢您的程序)。此外,CPU 需要分析您的代码,以查看您是实际使用引用后面的对象还是仅使用引用(请记住,同一个 CPU 可能运行 C/C++ 代码)。
-
不。这对 Java 来说是一个严重的性能问题。这就是为什么他们试图在 java9(或更高版本)中添加“值类型”,以便一个数组位于同一内存区域。
标签: java jvm jvm-hotspot prefetch java-memory-model