0%

堆内存和栈内存

我们常常做的是将Java内存区域简单的划分为两种: 一种叫做栈内存,一种叫做堆内存。

栈内存

栈内存又分两种,一种是虚拟机栈,一种是本地方法栈。

本地方法栈是去调用native方法服务,和java关系不算太大。

虚拟机栈就牛逼了,它里面存了局部变量表,操作栈,动态链接,方法出口等信息。

局部变量表存放了编译期可知的各种基本数据类型,对象引用和一条字节码指令的地址。
其中64位长度的long和double类型的数据会占用2个局部变量空间,其余的基本类型占1个。

当进入一个方法时,这个方法需要分配多大的局部变量空间是完全确定的,在运行期间不会改变变量表的大小。

在java虚拟机规范中,这个区域会有两种异常情况产生,如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常。如果没有处理好递归调用的出口条件,很容易就会报这样的错。

如果虚拟机栈动态扩展的时候无法申请最够的内存,就会抛出OutOfMemoryError异常。

堆内存

Java的堆是Java虚拟机所管理的内存中最大的一块。

堆的唯一目的就是存放对象实例。所有的对象实例都会在这里分配内存。

堆产生了一个对象之后,还能够在栈里面定义一个变量指向堆的的首地址。
如果这个对象没有被引用,那么不一会就会被java当作垃圾回收,因此Java堆是垃圾收集的管理主要区域。

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

参考资料

深入理解java虚拟机