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]存储?
理论上,堆栈有一个指向堆中包含数组本身的位置的指针.数组本身只是一个指针数组,它也指向堆中包含您引用的对象的位置.
在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",因为字符串文字无论如何都会存在于包的内存中,并且字符串是不可变的.没有必要为已经存在于内存中的字符串的精确副本分配额外的内存.
在实践中,唯一需要注意的是编译器根本不必将局部变量存储在堆栈中.如果它确定变量的范围足够短,则可以自由地优化掉堆栈引用并只使用寄存器.
在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[]:在这种情况下,数组本身仍然是堆上的连续块,但数组中的每个位置都包含实际值本身,而不是对堆上另一个位置的引用.