2012-04-19 22 views
21

我在这个主题上阅读过的很多书籍和文章,以及我用'不安全'写的一个小程序,都表明Java中的一维数组在内存中始终是连续的。那么它是由JLS规定还是实施惯例?这个问题被要求确认这个指示。Java:一维数组是否总是在内存中连续?

回答

10

由于在Java中没有真正的与内存地址交互的方式,所以在规范中也没有定义内存中对象布局的外观。

请注意,使用Unsafe几乎会自动意味着您正在漫游规范领域之外。这就是说,我敢说大多数JVM实现实际上使用线性布局(一维)数组。

3

鉴于许多JVM的有一个要求,即堆是连续在内存中,我认为它不太可能他们会在内存中的不同位置放置一个1d的基元数组。

Object []引用的对象不可能在内存中连续存在,即使它们是可以在没有警告的情况下重新排列。

注意:使用不安全,您可以读取数组中的引用作为int值,以查看GC之前和之后的内容。某些JVM使用64位引用,这需要很长的时间,但大多数情况下使用32位bti引用(即使是64位JVM)。

+2

同意,但阵列本身将是连续的,对不对?这样的事情:1000-> aa,1001-> bb,1002-> cd等 – shrini1000 2012-04-19 09:17:22

+1

我期望引用应该连续存储(但我不相信它在任何地方指定)这是类似的事实,即Spec没有说引用计数不会在任何JVM中用于GC,但是AFAIK没有。 – 2012-04-19 09:18:35

+3

@ shrini1000如果堆不是连续的虚拟内存块,则数组跨越两个片段将不会有连续的布局。另一方面,堆是连续的并不意味着数组也是这样,也许只是间接地使它更有可能,因为GC设计约束是相似的。 – 2012-04-19 09:27:50

8

我想用The Java Language Specification, Java SE 8 Edition (JLS)The Java Virtual Machine Specification, Java SE 8 Edition (JVMS)对此的看法来刷新此问题。

我们必须的选择,这个问题的答案:

  1. 在JVM实现强加什么约束。这是最可靠的方法,因为任何规范的实现固有地假定为“允许的所有不被禁止的”原理。
  2. 最令JVM实现合理的建议

我会指出来规范约束。

如果我们看一下第10章阵列的 JLS(以及相关的阵列JLSJVMS任何其他章节),我们找不到强加给数组的内存布局约束任何提及。 因此,它肯定意味着该阵列可能不是连续的

此外,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。堆

... 堆的内存不需要连续。

由于所有数组存储在堆和堆可能是不连续的,它遵循阵列也可能是不连续的。

+0

只是一个注释:[什么时候应该使用代码格式来处理非代码文本?](http://meta.stackoverflow.com/a/254995):)。 – Tom 2015-07-25 08:59:41

+0

我会如何处理官方规范中的类似引文?我希望将它们与其他文字分开以便更好地阅读。 – likern 2015-07-25 09:09:10

+0

请注意“代码格式”和“blockquote”之间的区别。诸如“JLS”,“JVMS”和“Chapter 10. Arrays”等词。没有代码,应该格式化为:)。引号是正确的。 – Tom 2015-07-25 09:21:23

相关问题