我在这个主题上阅读过的很多书籍和文章,以及我用'不安全'写的一个小程序,都表明Java中的一维数组在内存中始终是连续的。那么它是由JLS规定还是实施惯例?这个问题被要求确认这个指示。Java:一维数组是否总是在内存中连续?
回答
没有,JVM规范没有任何这样的保证: http://docs.oracle.com/javase/specs/jvms/se5.0/html/Concepts.doc.html#16446
在实践中它可能是这样,但你也没有这个字大小的保证。
不安全是不是一个标准的Java类,所以如果你的程序使用此,那么它是不可移植的反正...
由于在Java中没有真正的与内存地址交互的方式,所以在规范中也没有定义内存中对象布局的外观。
请注意,使用Unsafe
几乎会自动意味着您正在漫游规范领域之外。这就是说,我敢说大多数JVM实现做实际上使用线性布局(一维)数组。
鉴于许多JVM的有一个要求,即堆是连续在内存中,我认为它不太可能他们会在内存中的不同位置放置一个1d的基元数组。
Object []引用的对象不可能在内存中连续存在,即使它们是可以在没有警告的情况下重新排列。
注意:使用不安全,您可以读取数组中的引用作为int
值,以查看GC之前和之后的内容。某些JVM使用64位引用,这需要很长的时间,但大多数情况下使用32位bti引用(即使是64位JVM)。
我想用The Java Language Specification, Java SE 8 Edition (JLS)和The Java Virtual Machine Specification, Java SE 8 Edition (JVMS)对此的看法来刷新此问题。
我们必须的选择,这个问题的答案:
- 在JVM实现强加什么约束。这是最可靠的方法,因为任何规范的实现固有地假定为“允许的所有不被禁止的”原理。
- 最令JVM实现合理的建议
我会指出来规范约束。
如果我们看一下第10章阵列的 JLS(以及相关的阵列JLS和JVMS任何其他章节),我们找不到强加给数组的内存布局约束任何提及。 因此,它肯定意味着该阵列可能不是连续的。
此外,JLS说,阵列是对象:
第10章阵列。
在Java编程语言中,数组是 对象(第4.3.1节),被动态地创建,并且可以被分配给Object类型的 变量(§4.3.2)。类Object中的所有方法可能是在数组上调用 。
...4.3.1。对象。
一个目的是类实例或阵列。 (和阵列是Object)
并在同一时间JVMS说,对象和数组存储在堆上:
2.5.3。堆
Java虚拟机具有在所有Java虚拟机线程中共享的堆。 堆是运行时数据区域 ,从中分配所有类实例和数组的内存。
但JVMS不会强迫堆内存是连续的:
2.5.3。堆
... 堆的内存不需要连续。
由于所有数组存储在堆和堆可能是不连续的,它遵循阵列也可能是不连续的。
- 1. argv数组的元素在内存中是否总是连续的?
- 2. std :: array中的内存是否连续?
- 3. mmap是否连续分配堆内存?
- 4. 新[]是否连续分配内存?
- 5. pkt_data是否连续占用内存?
- 6. 二维数组的连续内存分配---释放内存
- 7. 数组是否连续存储在所有语言中?
- 8. 如何找到一个子数组是否在Java中的二维数组内有特定的总和?
- 9. 为整数的二维数组分配内存但它应该是连续的
- 10. 连续的'新'操作符是否连续分配内存?
- 11. 如何连续(连贯地)在C++内存中存储三维数组?
- 12. Java 2维整数数组检查是否存在
- 13. 在C++中,矢量是否占用连续的内存插槽?
- 14. 激活记录是否在内存中连续?
- 15. Android内存分配器 - 内存是否需要连续?
- 16. 确定元组中是否存在连续序列
- 17. 如何检查输入数组是否连续或不连续?
- 18. Typescript:搜索一个数组(行)是否存在于一个二维数组中
- 19. knockoutjs - 检查数组中是否存在项总是返回true
- 20. 是否构造函数总是需要一个内存分配
- 21. 动态二维数组非连续内存C++
- 22. 简单的函数来检查一个数组是否连续
- 23. 是否可以在一个数组中存储多个多维数组?
- 24. 是否存在与下划线(_)连续相反的内容?
- 25. 排序二维数组,数字应该是连续
- 26. 检查数值是否存在于多维数组中
- 27. NSData/Data存储是否连续?
- 28. 在Windows上,内存中的数据是否可以跨虚拟内存页连续存在?
- 29. 检查是否在一个PHP存在数组值多维数组
- 30. 什么是连续内存块?
同意,但阵列本身将是连续的,对不对?这样的事情:1000-> aa,1001-> bb,1002-> cd等 – shrini1000 2012-04-19 09:17:22
我期望引用应该连续存储(但我不相信它在任何地方指定)这是类似的事实,即Spec没有说引用计数不会在任何JVM中用于GC,但是AFAIK没有。 – 2012-04-19 09:18:35
@ shrini1000如果堆不是连续的虚拟内存块,则数组跨越两个片段将不会有连续的布局。另一方面,堆是连续的并不意味着数组也是这样,也许只是间接地使它更有可能,因为GC设计约束是相似的。 – 2012-04-19 09:27:50