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

发布于 2024-08-18 15:34:35 字数 170 浏览 11 评论 0原文

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

int a[];

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

I have an array declaration like this:

int a[];

Here a is an array of primitive int type. Where is this array stored? Is it stored on heap or stack? This is a primitve type int, all primitive types are not stored on heap.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

北方。的韩爷 2024-08-25 15:34:35

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

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.

梦归所梦 2024-08-25 15:34:35

它将存储在上,

因为数组是java中的对象。

编辑:如果您

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

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

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

烟火散人牵绊 2024-08-25 15:34:35

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

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.

梦巷 2024-08-25 15:34:35

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

大小为 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();
}

用 Double Still 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

Line

a[i] = qq.doubleValue();

进行初始化相当于

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

相当于

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

因为我们每次都会创建新的 Double 对象,所以我们会耗尽堆。
这表明 Double 类内的值存储在堆中。

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.

缘字诀 2024-08-25 15:34:35

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

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

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

流星番茄 2024-08-25 15:34:35

在示例 int arr[] = {10,20,30,40,50}; 中,数组本身及其值都将存储在堆中,而引用变量 arr 将存储在堆栈中。

In the example int arr[] = {10,20,30,40,50};, both the array itself and its values will be stored in the heap, while the reference variable arr will be stored in the stack.

风启觞 2024-08-25 15:34:35

我想有两种看待它的方法,当我们做这样的事情时

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

,我认为数组存储在堆中,只有引用变量“arr”存储在堆栈中。
但是,当我们执行类似 int arr[] = {10,20,30,40,50}; 的操作时,所有内容都存储在堆栈中

I guess there are two ways of looking at it, when we do something like this

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

than I think the array is stored in heap and only the reference ariable "arr" is stored in stack.
But when we do something like this int arr[] = {10,20,30,40,50}; then everything is stored in stack

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文