【问题标题】:Java Object[] and cache stradingJava Object[] 和缓存交换
【发布时间】:2015-06-27 15:16:49
【问题描述】:

正如我们所知,当内存移动到 cpu 上的 L 个缓存时,它会随着缓存线移动,因此整个缓存的性能优化...

在java中,当我们定义一个数组时,jmm保证每个元素的内存将被顺序分配。但是,如果我们有引用数组,这些引用可以随机指向内存中的不同位置。

我的问题是 java 是否按顺序分配实际对象内存?我们为此做了哪些优化?

例如,如果我们声明 int[],我们确信它们实际上在内存中都是连续的,但是如果我们定义一个包含两个 int 字段的 NewType(如 struct),并声明 NewType[],java 会发现是否按顺序保留实际内存?

【问题讨论】:

  • 好吧,也许我错了。 内存分配JVM不能混用。 JVM 会按照自己的感觉进行动态内存分配(从技术上讲,资源可用性在那个时间点是最好的)
  • 单个对象分配在单个块中。与此相关的是如果 GC 是深度或呼吸优先复制的事实。两种变体都存在于 Hotspot 中。在这里你可以找到它的一些方面:oracle.com/technetwork/server-storage/ts-6434-159339.pdf
  • Didint 很明白“GC 是深度或呼吸优先复制”你能给出几个链接吗? (谷歌搜索但没有找到合理的)

标签: java optimization memory-management jvm javac


【解决方案1】:

我的问题是 java 是否按顺序分配实际对象内存?

这不能保证,但大多数时候 OpenJDK/Oracle JVM 会保证。有些时候不是这样;

  • 当您在永久空间中分配大对象时,
  • 您的 TLAB 已满,您需要再购买一个。

但是,在 TLAB 中,它只是在内存中按顺序分配。

declare NewType[] java 是否会按顺序计算并保留实际内存?

Java 什么都想不出来,也没有想办法在内存中随机分配对象。通常,每个new 对象都将紧跟在最后一个之后。

【讨论】:

  • 顺便提一下 - GC 可能会移动分配的对象,因此即使它们最初是按顺序分配的,也不能保证它们会永远保持顺序
  • @SvetlinZarev 没错,但是,GC 并没有竭尽全力在内存中随机排列对象。相反,发现的顺序通常决定了位置。
  • 所以这意味着无论我们做什么,如果我们有引用类型数组,我们就会失去 cpu 缓存友好性?
  • 我的意思是,例如,我们可能有一个跨越两个连续 G1GC 区域的 LinkedList。并且 GC 循环可能只从第一个区域收集垃圾,然后将剩余的元素疏散到内存中某处的另一个区域,因此现在并非所有元素都是连续的。
  • @SvetlinZarev 是正确的,但他们中的大多数人在性能方面都会如此,这几乎没有什么区别。
【解决方案2】:

但是如果我们定义一个包含两个 int 字段的 NewType(如 struct),并声明 NewType[],java 是否会计算出并按顺序保留实际内存?

在这种情况下,java 对缓存不是很友好,因为除了基本类型之外,java 数组不是打包数据结构,它们是指向内存中其他地方分配的对象的引用数组。

即从数组到对象本身将至少有一层间接。这个问题通常被称为“指针追逐”。

即通常内存布局如下所示:

HlRRRRRRRRRRRRRRRRRRRRRRRRR0HR0iii0HR0iii0HR0iii0HR0iii0HR0iii0HR0iii0HR0iii0
         Array             | Obj  | Obj  | Obj  | Obj  | Obj  | Obj  | Obj  |

H = object header
l = array length
R = reference
i = int
0 = various types of padding

您可以使用jol 来检查对象的内存布局。

JDK 开发人员正在开发 Value types 作为 project valhalla 的一部分,这最终将允许打包数组存在,这可能需要作为 project panama 的一部分,但这仍然遥遥无期。

与此同时,还有旨在提供类似功能的 3rd 方项目:

其他项目要么使用堆外存储(例如通过sun.misc.Unsafe),要么使用ByteBuffer / byte[] 数组上的视图来创建打包的、缓存友好的数据结构,但代价是更复杂的API。

【讨论】:

  • 哇,谢谢,这么多有用的信息 :) 根本不知道 jol
猜你喜欢
  • 2011-02-04
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 1970-01-01
  • 2013-07-16
相关资源
最近更新 更多