Appearance
本篇文章将讲述什么是栈,以及栈与堆的区别,将通过对比分析堆栈与变量、数组和对象之间的内在联系。
堆和变量的关系
如图所示变量的值都存与栈中,和堆并无关系。
堆和数组的关系
观察如下代码,栈中存放变量,会将变量地址存放至栈中的局部变量表中,那么地址指向的就是堆,在堆中存放数组的数据。
注意看下面代码,当执行x=null时,x引用的内存地址被删除,那么x数组在堆中的值会被删除吗?答案是不会,堆中的0x0001任然被y引用,堆中的数据会一直存在,不会被垃圾回收算法删除。
java
public static void main(String[] args) {
int[] x = new int[5];
x[0] = 100;
int[] y = x;
x = null;
}
堆和对象的关系
如图所示,和数组类似,堆存储对象的值,栈存储的地址指向堆。
如果book2
指向book1
,那么堆不会重新开辟空间,而是直接引用book1的空间
总结
栈:
- 基本数据类型、局部变量存放在栈帧内,方法执行完毕(栈帧出栈)立即释放,节约空间。
- 栈帧内的变量,没有默认值,需要手工设置。
- 栈帧只存留在单个线程中,其他线程访问不了。
- 可以使用-Xss来定义栈内存大小。
- 当堆栈内存已满时,Java运行时抛出
java.lang.StackOverFlowError
堆:
- 数组和对象存于堆中,用完后(栈帧不再引用),靠垃圾回收算法清除。
- 堆内对象的变量都有默认值。
- 所有的线程共享堆,即所有栈帧的变量都能引用堆的内存地址。
- 可以使用-Xms和-Xmx的JVM选项来定义堆内存的启动大小和最大大小。
- 如果堆内存已满,则抛出
java.lang.OutOfMemoryError
: Java堆空间错误。