90

我有一个这样的数组声明:

int a[];

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

4

5 回答 5

149

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

例如,考虑一下:

public class Foo
{
    int value;
}
...

public void someOtherMethod()
{
    Foo f = new Foo();
    ...
}

现在,f.value住在哪里?神话表明它在堆栈上 - 但实际上它是新Foo对象的一部分,并且存在于堆1上。(请注意,其f自身的值是一个引用,并且存在于堆栈中。)

从那里开始,数组是一个简单的步骤。您可以将数组视为许多变量 -new int[3]这有点像拥有这种形式的类:

public class ArrayInt3
{
    public readonly int length = 3;
    public int value0;
    public int value1;
    public int value2;
}

1事实上,它比这更复杂。堆栈/堆的区别主要是实现细节 - 我相信一些 JVM,可能是实验性的,可以判断对象何时永远不会从方法中“逃脱”,并且可以在堆栈上分配整个对象。但是,如果您选择关心,它在概念上是在堆上的。

于 2010-01-20T07:38:23.197 回答
39

它将存储在堆上

因为数组是java中的一个对象。

编辑 :如果你有

int [] testScores; 
testScores = new int[4];

将此代码想象为对编译器说:“创建一个包含四个整数的数组对象,并将其分配给名为 的引用变量testScores。此外,继续将每个int元素设置为零。谢谢。”

于 2010-01-20T07:32:04.757 回答
25

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

于 2010-01-20T07:34:38.977 回答
21

我只是想分享一些我在这个主题上运行的测试。

大小为 1000 万的数组

public static void main(String[] args) {
    memInfo();
    double a[] = new double[10000000];
    memInfo();
}

输出:

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

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

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

public static void main(String[] args) {
    memInfo();
    Double a[] = new Double[10000000];
    memInfo();
}

输出将显示 40MB。我们只有双重引用,它们没有被初始化。

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

还是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

线

a[i] = qq.doubleValue();

相当于

a[i] = Double.valueOf(qq.doubleValue());

这相当于

a[i] = new Double(qq.doubleValue());

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

于 2013-05-01T21:11:40.170 回答
2

在 Java 编程语言中,数组是对象,是动态创建的,并且可以分配给 Object 类型的变量。

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html

于 2010-01-20T07:33:32.663 回答