Is a Java array of primitives stored in stack or heap?
Solution 1
As gurukulki said, it's stored on the heap. However, your post suggested a misunderstanding probably due to some well-intentioned person propagating the myth that "primitives always live on the stack". This is untrue. Local variables have their values on the stack, but not all primitive variables are local...
For example, consider this:
public class Foo
{
int value;
}
...
public void someOtherMethod()
{
Foo f = new Foo();
...
}
Now, where does f.value
live? The myth would suggest it's on the stack - but actually it's part of the new Foo
object, and lives on the heap1. (Note that the value of f
itself is a reference, and lives on the stack.)
From there, it's an easy step to arrays. You can think of an array as just being a lot of variables - so new int[3]
is a bit like having a class of this form:
public class ArrayInt3
{
public readonly int length = 3;
public int value0;
public int value1;
public int value2;
}
1 In fact, it's more complicated than this. The stack/heap distinction is mostly an implementation detail - I believe some JVMs, possibly experimental ones, can tell when an object never "escapes" from a method, and may allocate the whole object on the stack. However, it's conceptually on the heap, if you choose to care.
Solution 2
It will be stored on the heap
because array is an object in java.
EDIT : if you have
int [] testScores;
testScores = new int[4];
Think of this code as saying to the compiler, "Create an array object that will hold four ints, and assign it to the reference variable named testScores
. Also, go ahead and set each int
element to zero. Thanks."
Solution 3
It is an array of primitive types which in itself is not primitive. A good rule of thumb is when the new keyword is involved the result will be on the heap.
Solution 4
I just wanted to share few tests I ran on this subject.
Array of size 10 million
public static void main(String[] args) {
memInfo();
double a[] = new double[10000000];
memInfo();
}
Output:
------------------------
max mem = 130.0 MB
total mem = 85.0 MB
free mem = 83.6 MB
used mem = 1.4 MB
------------------------
------------------------
max mem = 130.0 MB
total mem = 130.0 MB
free mem = 48.9 MB
used mem = 81.1 MB
------------------------
As you see used heap size is increased by ~80 MB, which is 10m * sizeof(double).
But if we have use Double instead of double
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
memInfo();
}
Output will show 40MB. We only have Double references, they are not initialized.
Filling it with Double
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq;
}
memInfo();
}
Still 40MB. Because they all point to same Double object.
Initializing with double instead
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq.doubleValue();
}
memInfo();
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Line
a[i] = qq.doubleValue();
is equivalent to
a[i] = Double.valueOf(qq.doubleValue());
which is equivalent to
a[i] = new Double(qq.doubleValue());
Since we create new Double objects each time, we blow out the heap. This shows values inside the Double class are stored in heap.
Solution 5
In the Java programming language arrays are objects, are dynamically created, and may be assigned to variables of type Object.
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html
user241924
Updated on July 12, 2022Comments
-
user241924 almost 2 years
I have an array declaration like this:
int a[];
Here
a
is an array of primitiveint
type. Where is this array stored? Is it stored on heap or stack? This is a primitve typeint
, all primitive types are not stored on heap. -
Zaki over 14 yearsAnd the reference variable named testScores(pointing to the array on the heap) will be on the stack.
-
mob over 14 yearsThe code only says "Thanks" if you supply the
-g
option to the compiler. Otherwise it will be optimized away. -
Guido almost 13 yearsAbout the "escape analyisis" in Java: blog.juma.me.uk/2008/12/17/objects-with-no-allocation-overhead It says that it is present since the early access release of JDK 6 Update 14, and enabled by default since JDK 6 Update 23.
-
Malachiasz about 10 yearsdoes it change anything if array is public static final? Shouldn't it be part of the constant pool then?
-
Jon Skeet about 10 years@Malachiasz: Nope. An array is never a constant.
-
supercat almost 10 years@JonSkeet: In all versions of the Java library I'm aware of, every
String
is backed by achar[]
. I believe literal strings are stored in the public constant pool; for GC optimization, that would imply that the backing arrays should be stored likewise (otherwise the constant pool would have to be scanned during any GC cycle where the backing array would otherwise be eligible for collection). -
Jon Skeet almost 10 years@supercat: Yes, that would make sense. But any array you declare yourself never ends up as part of the constant pool.
-
Rob L almost 10 yearsSkeet knows everything about programming! Great explanation.
-
Code-Apprentice over 9 years@mob You are making an assumption that this is the only code. It is probably better to assume that these two lines are part of a larger program which actually uses the array.
-
hedleyyan over 5 yearsCould you paste the code detail of memInfo() pls? :)