Java中堆和栈
数据结构中的堆和栈
- 栈:实际上就是满足后进先出的性质,是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。
- 堆:堆是一种完全二叉树或者近似完全二叉树,完全二叉树是效率很高的数据结构,像十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化。
系统方面的堆和栈
- 栈:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。
- 堆:堆内存存储的是数组和对象,一般new建立的都是在堆中,堆中存放的都是实体对象,实体一般是用于封装数据的,堆中的实体不会随时释放,但是会被当成垃圾,Java中有垃圾回收机制会不定时的收取。
-
下面用一个事例详细解释一下堆和栈,比如主函数中的语句: int [] arr = new int [2];这句在内存中是怎么被定义的呢?主要流程如下:
- 主函数先入栈,在栈里面定义一个变量 arr。
- 接下来为arr 赋值,但这里的并不是一个具体值,而是一个实体。
- 实体是创建在堆里面的,通过new开辟一个内存空间。(内存中存储数据都是通过地址来体现的,此时为这个实体分配一个内存地址)
- 经过以上步骤之后,栈创建了变量,堆创建了实体,那么怎么将两个联系起来呢?
- 因为堆分配了一个地址给实体的,那么将这个地址赋值给变量 arr,此时arr就可以通过地址指向了数组,arr 要是想操作数组是,就可以通过该地址。
- int [] arr = new int [2]; 这句并不是直接将实体赋值给 arr,这种我们就不叫基本数据类型,而叫引用数据类型,此句称为 arr 引用了堆内存当中的实体。
堆和栈的区别
- 综上所述,堆和栈的区别很明显:
- 栈内存存储的是局部变量而堆内存存储的是实体。
- 栈内存的更新速度要快于堆,因为局部变量离开了作用域就会释放。
- 栈内存存放的变量一旦离开了作用域(方法)就会被释放,而堆内存的实体只会被垃圾回收机制不定时的回收。
JVM 的内存划分
- 寄存器
- 本地方法区
- 方法区
- 栈内存
- 堆内存