35

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.

shrini1000
  • 7,038
  • 12
  • 59
  • 99

4 Answers4

29

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...

Mathias Schwarz
  • 7,099
  • 23
  • 28
18

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:

  1. 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.
  2. 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.

user207421
  • 305,947
  • 44
  • 307
  • 483
likern
  • 3,744
  • 5
  • 36
  • 47
  • 1
    Just a note: [When should code formatting be used for non-code text?](http://meta.stackoverflow.com/a/254995) :). – Tom Jul 25 '15 at 08:59
  • How would I do the similar citations from official specification? I want isolate them from other text for better reading. – likern Jul 25 '15 at 09:09
  • 1
    Please mind the difference between "code formatting" and "blockquote". Words like "JLS", "JVMS" and "Chapter 10. Arrays." are no code and should be formatted as such :). The quotes are correct. – Tom Jul 25 '15 at 09:21
  • 5
    It does not follow from the entire heap not being contiguous that any specific object may not be contiguous. This might be a fact but it does not follow from this premiss, or therefore from the fact that arrays are objects either. – user207421 Sep 18 '21 at 08:00
12

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.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • It's interesting that Java permits "Unsafe" code in this context but provides no goto keyword. – nicomp Sep 18 '21 at 13:38
  • @icomp: Java doesn't permit Unsafe. In fact it's not part of the platform. It's an implementation detail of one specific implementation. In fact it's gone in the newest Java versions (still used internally in one form or another, but inaccessible to user code). Goto would be a hot mess in Java, because it basically breaks any static prediction of what the stack is allowed to look like at any given point in the method execution which is an important part of byte code verification (i.e. checking that methods are sane). – Joachim Sauer Sep 18 '21 at 13:59
7

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)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    agreed, but the array itself will be contiguous, right? something like this: 1000->aa, 1001->bb, 1002->cd etc. – shrini1000 Apr 19 '12 at 09:17
  • 1
    I would expect the references should be stored continously (but I don't believe it is specified anywhere) This is similar to the fact that the Spec doesn't say reference counting won't be used for GC in any JVM, but AFAIK none do. – Peter Lawrey Apr 19 '12 at 09:18
  • 3
    @shrini1000 if the heap is not a contiguous block of virtual memory, then an array spannig two fragments will NOT have contiguous layout. On the other hand, the heap being contiguous implies nothing about arrays being that too, maybe just indirectly makes it more likely since the GC design constraints would be similar. – Marko Topolnik Apr 19 '12 at 09:27
  • 3
    @MarkoTopolnik Also my thought is that if they didn't see the need to break up the heap (which is a pain on 32-bit Windows) I don't see why they would do it for a single array. – Peter Lawrey Apr 19 '12 at 09:29
  • 1
    @PeterLawrey Exactly, that's what I meant by "similar design constraints". It would be pointless to insist on a contiguous heap and then bring all the trouble back in by allowing fragmented arrays. – Marko Topolnik Apr 19 '12 at 09:33
  • @Marko Topolnik if the array is already created, it won't get fragmented, and if it is to be created and not enough contiguous space is available, GC would first compact the fragments, right? – shrini1000 Apr 19 '12 at 09:33
  • @shrini1000 Yes, that's the behavior that I would reasonably expect. – Marko Topolnik Apr 19 '12 at 09:35
  • If after a GC there is not enough continous memory you will get an OutOfMemoryError. The CMS GC doesn't defragment so you can get such a failure even though it says there are many MB free. – Peter Lawrey Apr 19 '12 at 09:40