Java: are 1-d arrays always contiguous in memory?
Many books/articles I've read on this topic, as well as a small program I wrote using 'Unsafe', indicate that 1-d arrays in Java are always contiguous in memory. So is it dictated by JLS or is it an implementation convention? The question is asked to confirm this indication.
No, the JVM specification does not have any such guarantees: http://docs.oracle.com/javase/specs/jvms/se5.0/html/Concepts.doc.html#16446
In practice it is probably the case but you also have no guarantee about the word size.
Unsafe is not a standard Java class, so if your program uses this, then it is not portable anyway...
I want to refresh this question with what The Java Language Specification, Java SE 8 Edition (JLS) and The Java Virtual Machine Specification, Java SE 8 Edition (JVMS) are saying about it.
We have to choices to answer to this question:
- What constraints are imposed on JVM implementations. This is the most reliable approach because implementation of any specification inherently presume of "Everything which is not forbidden is allowed" principle.
- What most JVM implementations suggest reasonable.
I will point out to specification constraints.
If we look at Chapter 10. Arrays of the JLS (and any other chapters of JLS and JVMS related to arrays) we couldn't find any mention of memory layout constraints imposed to arrays. Thus it definitely means that array might be not continuous.
Moreover, JLS says that arrays are Objects:
Chapter 10. Arrays.
In the Java programming language, arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array. ...
4.3.1. Objects.
An object is a class instance or an array. (and Array is Object)
And at the same time JVMS says that objects and arrays are stored on the heap:
2.5.3. Heap
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
But JVMS doesn't compel heap memory to be continuous:
2.5.3. Heap
... The memory for the heap does not need to be continuous.
As all arrays are stored in heap and heap might be not continuous, it follows that arrays also might be not continuous.
Since there is no real way to interact with memory addresses in Java, it is also not defined in the spec how the layout of object in memory looks.
Note that using Unsafe
pretty much automatically means that you're strolling outside the realm of the spec.
That being said, I'd venture that most JVM implementations do in fact use a linear layout for (one-dimensional) arrays.
Given that many JVM's have a requirement that the heap is continous in memory I think its unlikely they will place a 1d array of primitives in different places in memory.
The object referenced by an Object[] are unlikely to be continous in memory and even if they are, can be re-arranged without warning.
Note: Using Unsafe you can read references in an array as int
values to see what they are before and after a GC. Some JVMs use 64-bit references which require a long, but most use 32-bti references (even for 64-bit JVMs)