1 《深入理解Java虚拟机》
2 https://www.cnblogs.com/niejunlei/p/5987611.html
3 https://blog.csdn.net/ZhongGuoZhiChuang/article/details/53940562
4 https://blog.csdn.net/seebetpro/article/details/49202037
Java虚拟机栈中存储的内容,它用于存储数据和部分过程结果的数据结构,同时也被用来处理动态链接/方法返回值和异常分派.
一个完整的栈帧包括:局部变量表/操作数栈/动态链接信息/方法正常完成和异常完成信息.
Java虚拟机栈是描述Java方法运行过程的内存模型.Java虚拟机会为每一个即将运行的Java方法创建一块叫做”栈帧”的区域,这块区域用于存储该方法在运行过程中所需要的一些信息,这些信息包括:
局部变量表:(由若干个Slot组成,长度由编译器决定,单个Slot可以存储一个类型为boolean/byte/char/short/float/reference/returnAddress的数据,两个Slot可以存储一个类型为long或者double的数据)
局部变量表是一组变量值的存储空间,它用于存储方法,参数,以及方法内部定义的局部变量。在java编译器编译class的时候就在该方法的code属性中确定了该方法所需的最大容量,局部变量表中的变量槽也就是Slot为最小单位,java虚拟机中并没有指明一个Slot所需要占用的内存空间大小,只是非常有导向性的描述到任何一个Slot都应该能存放一个布尔型,字节型,字符型,短整型,整形,浮点型,reference类型以及returnAddress类型的数据在这8种数据类型之中,他们的共同特征是都可以使用32位或者更小的内存空间来进行存放,但Java虚拟机这样描述Slot的空间与明确指出每个Slot应该占用32位内存还是有差别的,他这种描述允许Slot的内存空间随着处理器,操作系统或者java虚拟机的具体实现而发生变化,假如在64位的java虚拟机之中使用了64位的内存空间去实现一个Slot,java虚拟机仍然要使用对齐或者补白的手段,让Slot在外观上看出来了与32位的java虚拟机之中是一致的。
当一个方法即将被运行时,Java虚拟机首先会在Java虚拟机中为该方法创建一块”栈帧”,栈帧中包含局部变量表\操作数栈\动态链接\方法出口信息等.当方法在运行过程中需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中.
当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放内存空间.
经常会有人说:Java内存空间分为”栈”和”堆”,栈中存放局部变量,堆中存放对象.
上述表达并不完全正确!这里的堆可以这么理解,但是这里的栈只代表了Java虚拟机栈中的局部变量表部分.真正的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表/操作数栈/动态链接/方法出口信息.
a) 如果Java虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就会抛出StackOverflowError异常.
b) 如果Java虚拟机栈的内存大小允许动态扩展,且当线程请求栈是内存用完了,无法再动态扩展了,此时就会抛出OutOfMemoryError异常.
java虚拟机栈和程序计数器一样,他是线程私有的内存区域,他的生命周期与线程相同,java虚拟机栈描述的是java方法执行时候的内存概念模型,每个方法在执行的时候都会创建一个栈帧,用来创建这个方法的操作数栈,局部变量表,方法出口,动态链接等信息,每一个方法在调用和结束的过程就对应了一个栈帧在虚拟机栈中入栈到出栈的过程,java虚拟机栈是一个后进先出栈,靠后执行的方法会优先完成,后面进入虚拟机栈的栈帧优先被出栈,这与我们平时执行java方法的印象是一致的,在程序执行中java方法的调用,执行和退出,都与java虚拟机栈里面存储的栈帧有着密切的联系。
OutOfMemoryError和StackOverflowError区别?
StackOverflowError表示当前线程申请的栈超过了事先定好的栈的最大深度,但是内存空间可能还有很多.而OutOfMemoryError是指当前线程申请栈时发现栈已经满了,而且内存也都已经用光了.