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

问题描述 投票:0回答:6

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

int a[];

这里

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

java arrays heap-memory primitive-types stack-memory
6个回答
162
投票

正如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(可能是实验性的)可以判断对象何时从方法中“逃逸”,并且可以在堆栈上分配整个对象。然而,如果您选择关心的话,它“概念上”在堆上。


43
投票

因为数组是java中的对象。

编辑

:如果你有 int [] testScores; testScores = new int[4];

将此代码视为对编译器说:“创建一个包含四个整数的数组对象,并将其分配给名为 
testScores

的引用变量。另外,继续将每个

int
元素设置为零。谢谢。 ”
    


27
投票


23
投票

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。我们只有双引用,它们没有初始化。

用双倍填充它

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 类内的值存储在堆中。


3
投票

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


0
投票

int arr[] = new int[4]; for( int i=0;i<=3;i++ ){ arr[i] = i*10; }

我认为数组存储在堆中,只有引用变量“arr”存储在堆栈中。
但是当我们做这样的事情时
int arr[] = {10,20,30,40,50};

那么所有的东西都存储在堆栈中

之前的说法并不完全准确。在示例 int arr[] = {10,20,30,40,50}; 中,数组本身及其值都将存储在堆中,而引用变量 arr 将存储在堆栈中。

© www.soinside.com 2019 - 2024. All rights reserved.