堆和栈的区别
栈是运行时的单位,而堆是存储的单位。
- 堆:解决的是数据存储的问题,即数据怎么放、放在哪儿。(线程共享)
- 栈:解决程序的运行问题,即程序如何执行,或者说如何处理数据;(线程独享)
在Java中一个线程就会相应有一个线程栈与之对应。这点很容易理解,因为不同的线程执行逻辑有所不同,因此需要一个独立的线程栈。而堆则是所有线程共享的。栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。
为什么要堆和栈分离?
- 栈代表了处理逻辑,而堆代表了数据,使得处理逻辑更为清晰;
- 使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象),一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间
- 栈运行时需要进行地址段的划分,只能向上增长,限制了其存储能力,而堆不同,堆中的对象是可以动态增长的,因此拆分后才可以做到动态增长,而栈中只需要记录堆得内存地址即可;
- 面向对象就是堆和栈的完美结合,对象的属性其实就是数据,存放在堆中;而对象的行为(方法),就是运行逻辑,放在栈中
- 堆栈分离才实现了垃圾回收机制
注意:栈的大小通过-Xss来设置,当栈中存储数据比较多时,需要适当调大这个值,否则会出现java.lang.StackOverflowError异常