正如我们所知道的,当内存被移动到cpu上的L缓存时,它是用单身汉移动的,因此整个缓存加载性能优化.
在java中,当我们定义数组时,jmm保证每个元素的内存将按顺序分配。但是,如果我们有数组的引用,这些引用可以随机地指向内存中的不同位置。
我的问题是java是否按顺序分配实际对象内存?我们在引擎盖下面有哪些优化?
例如,如果我们声明int[],那么我们确信这些都是内存中的序列,但是如果我们定义一个包含两个int字段的NewType (类似于struct),并且声明NewType[],那么NewType[]是否会按照顺序地计算和保存实际内存呢?
发布于 2015-06-27 15:42:10
我的问题是,java是否按顺序分配实际对象内存?
这并不一定,但大多数情况下,OpenJDK/Oracle JVM是这样做的。有些时候,情况并非如此;
然而,在TLAB中,它只是在内存中依次分配。
声明NewType[]会计算出并按顺序保留实际内存吗?
Java没有计算出任何东西,也没有超出它在内存中随机分配对象的方式。通常,每个new对象都将紧接在最后一个对象之后。
发布于 2015-06-27 18:04:14
但是,如果我们定义一个包含两个int字段的NewType (如struct),并声明NewType[],那么NewType[]是否会按照顺序地计算和保留实际内存呢?
在这个场景中,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您可以使用约尔检查对象的内存布局。
JDK正在开发价值类型,将其作为瓦尔哈拉项目的一部分,最终允许打包数组存在,这可能是巴拿马项目的一部分,但这还远远不够。
与此同时,还有一些旨在提供类似功能的第三方项目:
其他项目要么使用堆外存储(例如通过sun.misc.Unsafe),要么使用ByteBuffer / byte[]数组上的视图来创建打包的、对缓存友好的数据结构,而牺牲更复杂的API。
https://stackoverflow.com/questions/31090242
复制相似问题