存储在堆栈或堆中的Java基元数组是?

use*_*924 81 java arrays heap stack primitive-types

我有这样的数组声明:

int a[];
Run Code Online (Sandbox Code Playgroud)

a是一个原始int类型的数组.这个数组存储在哪里?它是存储在堆还是堆栈上?这是一个原始类型int,所有原始类型都不存储在堆上.

Jon*_*eet 143

正如gurukulki所说,它存储在堆上.然而,你的帖子暗示了一个误解可能是由于一些善意的人传播了"原始人总是生活在堆栈中"的神话.这是不真实的.局部变量在堆栈上有它们的值,但并非所有原始变量都是局部的......

例如,考虑一下:

public class Foo
{
    int value;
}
...

public void someOtherMethod()
{
    Foo f = new Foo();
    ...
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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.


Gur*_*lki 36

它将存储在堆上

因为array是java中的一个对象.

编辑 :如果你有

int [] testScores; 
testScores = new int[4];
Run Code Online (Sandbox Code Playgroud)

想想这段代码对编译器的说法,"创建一个将保存四个整数的数组对象,并将其分配给名为的引用变量testScores.另外,继续并将每个int元素设置为零.谢谢."

  • 如果你为编译器提供`-g`选项,代码只会说"谢谢".否则它将被优化掉. (10认同)
  • 名为testScores的引用变量(指向堆上的数组)将在堆栈上. (2认同)

Esb*_*sen 20

它是一个原始类型的数组,它本身并不是原始的.一个好的经验法则是当涉及new关键字时,结果将在堆上.


ach*_*n55 16

我只想分享一些关于这个主题的测试.

阵列大小1000万

public static void main(String[] args) {
    memInfo();
    double a[] = new double[10000000];
    memInfo();
}
Run Code Online (Sandbox Code Playgroud)

输出:

------------------------
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
------------------------
Run Code Online (Sandbox Code Playgroud)

如您所见,使用的堆大小增加了~80 MB,即10m*sizeof(double).

但是如果我们使用Double而不是double

public static void main(String[] args) {
    memInfo();
    Double a[] = new Double[10000000];
    memInfo();
}
Run Code Online (Sandbox Code Playgroud)

输出将显示40MB.我们只有Double引用,它们没有初始化.

用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();
}
Run Code Online (Sandbox Code Playgroud)

还是40MB.因为它们都指向同一个Double对象.

用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.doubleValue();
    }
    memInfo();
}

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Run Code Online (Sandbox Code Playgroud)

线

a[i] = qq.doubleValue();
Run Code Online (Sandbox Code Playgroud)

相当于

a[i] = Double.valueOf(qq.doubleValue());
Run Code Online (Sandbox Code Playgroud)

这相当于

a[i] = new Double(qq.doubleValue());
Run Code Online (Sandbox Code Playgroud)

由于我们每次都会创建新的Double对象,因此我们会将堆炸出来.这表明Double类中的值存储在堆中.

  • 您能粘贴 memInfo() 的代码详细信息吗?:) (4认同)