数组在java中保存在内存中的位置?

Gre*_*Oks 12 java memory arrays heap stack

如果我有一个函数,在该函数中我声明:

Object arr[] = new Object[20];
Run Code Online (Sandbox Code Playgroud)

arr和整个数组存储在哪里?堆?堆?声明是在某个函数中还是在main()中是否重要?

并且假设我也有这些命令行:

arr[0] = new String("abc");
arr[1] = new List();
Run Code Online (Sandbox Code Playgroud)

哪里arr[0]arr[1]存储?

Nay*_*uki 13

记忆图:

记忆图

框是内存位置(可以存储二进制数).
箭头是内存引用(即指针).


Str*_*ior 8

理论上,堆栈有一个指向堆中包含数组本身的位置的指针.数组本身只是一个指针数组,它也指向堆中包含您引用的对象的位置.

在Java中,您可以非常依赖这样一个事实:只要您说new ...,就在堆中创建空间.一般来说,只要声明变量,编译器就会在方法的上下文中为该变量保留堆栈空间.对于本机类型,该空间将保存实际字节以表示该值.对于对象和数组,该变量将保存内存引用.

因此,例如,以下对象在堆中为它们分配了单独的内存位置:

new Object[20]
new String("abc")
new List() // This contains a reference to an initial array, which is also on the heap.
Run Code Online (Sandbox Code Playgroud)

请注意,很少有时候new String("abc")优先"abc",因为字符串文字无论如何都会存在于包的内存中,并且字符串是不可变的.没有必要为已经存在于内存中的字符串的精确副本分配额外的内存.

在实践中,唯一需要注意的是编译器根本不必将局部变量存储在堆栈中.如果它确定变量的范围足够短,则可以自由地优化掉堆栈引用并只使用寄存器.


Dan*_*Tao 5

在Java中,基本上每次使用new关键字时,都要在堆上为要存储的对象分配空间.

用于指向该对象的变量包含存储在堆栈中的引用.

例如:

                                    // This array object is
                                    // stored on the heap.
String[] arr                      = new String[5];
// This reference (arr) is stored
// in a variable on the stack.
Run Code Online (Sandbox Code Playgroud)

在像a这样的引用类型数组的情况下,Object[]分配的空间是一个足够大的连续块,可以存储数组将保存的许多引用.任何特定的引用,例如at arr[0],都将指向堆上存储单个对象的另一个位置.

The array, somewhere on the heap:
[a*][b*][  ][  ][  ]

a (elsewhere on the heap):
"abc"

b (yet another heap location):
[A List object]
Run Code Online (Sandbox Code Playgroud)

唯一的例外是基元数组,例如int[]:在这种情况下,数组本身仍然是堆上的连续块,但数组中的每个位置都包含实际值本身,而不是对堆上另一个位置的引用.