是否从 Java 中的引用数组中预取对象?

Are objects prefetched from an array of references in Java?

假设我们有 1000 个相同类型的对象分散在内存中(它们是在不同时间创建的,其他对象也在其间创建)。

我们有一个数组,其中包含对 1000 个对象中每个对象的引用。

问题

如果我们按顺序遍历数组,什么将被预取到 CPU 的缓存中?只有数组保存的引用或者这些引用将被解除引用并将对象加载到缓存中?

Java(JVM)是​​否实现了某种软件预取?如果没有,是否有提供软件预取的库?

经过一些研究,最常见的 JVM 实现 (HotSpot) 用于 support prefetching. But this has been removed,因为它们没有实际用途。感谢@apangin link 错误报告。

正如@markspace 提到的,对象在收集期间被重新安排以便于访问 - 这称为“压缩”,并且出现在 HotSpot 使用的默认 GC 中。您无需担心此类底层细节,因为 VM 会为您处理。

更深入地了解压缩..

您可能听说过“Stop-The-World”——当对象图处于不一致状态时会发生这种情况。对象正在四处移动,因此线程可能会访问不再存在的对象。有一些 GC 实现被认为是“无间断的”,例如 ,它使用转发指针允许线程访问最近移动的对象。

重点是,您无需担心对象在内存中的位置,或者该位置与另一个对象的距离。 VM 旨在为您做出这些决定。

最终答案

那么,对象是从引用数组中预取的吗? 你真的不应该担心。您使用 Java 不必关心这些底层细节。

如果您真的对这些细节感兴趣(也许您遇到了一些奇怪的错误),正如我之前提到的,它是特定于实现的,您必须具体说明您的实现重新参考。

虽然,正如我之前所说,它是 Java;停止担心你不需要担心的事情。我怎么强调都不为过。