Java:1-d数组在内存中总是连续的吗?

2022-09-01 06:41:23

我读过的许多关于这个主题的书/文章,以及我用“Unsafe”编写的一个小程序,都表明Java中的1-d数组在内存中总是连续的。那么,它是由JLS决定的还是一个实现约定呢?提出问题以确认此适应症。


答案 1

不,JVM 规范没有任何此类保证:http://docs.oracle.com/javase/specs/jvms/se5.0/html/Concepts.doc.html#16446

在实践中,情况可能就是这样,但您也不能保证字的大小。

Unsafe不是一个标准的Java类,所以如果你的程序使用它,那么它无论如何都是不可移植的......


答案 2

我想用 Java Language Specification, Java SE 8 Edition (JLS)The Java Virtual Machine Specification, Java SE 8 Edition (JVMS) 来刷新这个问题。

我们必须选择来回答这个问题:

  1. 对 JVM 实现施加了哪些约束。这是最可靠的方法,因为任何规范的实现本质上都假定“不允许任何不被禁止的东西”原则。
  2. 大多数JVM实现所建议的合理性。

我将指出规范约束。

如果我们看一下第10章。 JLS的数组(以及与数组相关的JLS和JVMS的任何其他章节)我们找不到任何提及强加给数组的内存布局约束。因此,这绝对意味着数组可能不是连续的。

此外,JLS说数组是对象:

第 10 章。阵 列。

在 Java 编程语言中,数组是对象 (§4.3.1),是动态创建的,可以分配给 Object 类型的变量 (§4.3.2)。可以在数组上调用类 Object 的所有方法。...

4.3.1. 对象。

对象是类实例或数组。(数组是对象)

同时,JVMS表示对象和数组存储在堆上:

2.5.3. 堆

Java 虚拟机具有一个在所有 Java 虚拟机线程之间共享的堆。堆是运行时数据区域,从中为所有类实例和数组分配内存。

但是 JVMS 不会强制堆内存是连续的:

2.5.3. 堆

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

由于所有数组都存储在堆中,并且堆可能不是连续的,因此数组也可能不连续。