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

时间:2012-04-19 09:05:26

标签: java arrays

我读过很多关于这个主题的书籍和文章,以及我用'Unsafe'编写的一个小程序,表明Java中的1-d数组在内存中总是连续的。它是由JLS规定还是实施惯例?要求提出这个问题的确认。

4 个答案:

答案 0 :(得分:19)

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

在实践中可能就是这种情况,但您也无法保证字数。

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

答案 1 :(得分:10)

由于没有真正的方法与Java中的内存地址进行交互,因此在规范中也没有定义内存中对象的布局如何。

请注意,自动使用Unsafe意味着您在规范范围之外漫步。

话虽如此,我敢说大多数JVM实现实际上使用线性布局(一维)数组。

答案 2 :(得分:10)

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

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

  1. 对JVM实施施加了哪些约束。这是最可靠的方法,因为任何规范的实现都固有地假定“所有不被禁止的东西”原则。
  2. 大多数JVM实施建议合理
  3. 我将指出规范约束。

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

    此外, JLS 表示数组是 Objects

      

    第10章阵列。

         

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

         

    4.3.1。对象。

         

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

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

      

    2.5.3。堆

         

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

    但是 JVMS 并不会迫使堆内存连续:

      

    2.5.3。堆

         

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

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

答案 3 :(得分:4)

鉴于许多JVM都要求堆在内存中连续存在,我认为不太可能将1d基元数组放在内存中的不同位置。

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

注意:使用Unsafe,您可以将数组中的引用读取为int值,以查看GC之前和之后的内容。一些JVM使用64位引用,这些引用需要很长但大多数使用32-bti引用(即使对于64位JVM)