操纵数栈也常被称为操纵栈,它是一个后入先出(Last In First Out, LIFO)栈。同局部变量表一样,操纵数栈的最大深度也在编译的时辰被写入到Code属性的max_stacks数据项之中。操纵数栈的每一个元素可所以恣意的Java数据范例,包罗long和double。32位数据范例所占的栈容量为1,64位数据范例所占的栈容量为2。在要领执行的任何时辰,操纵数栈的深度都不会高出在max_stacks数据项中设定的最大值。
当一个要领方才开始执行的时辰,这个要领的操纵数栈是空的,在要领的执行进程中,会有各类字节码指令向操纵数栈中写入和提取内容,也就是入栈出栈操纵。譬喻,在做算术运算的时辰是通过操纵数栈来举办的,又可能在挪用其他要领的时辰是通过操纵数栈来举办参数转达的。
举个例子,整数加法的字节码指令iadd在运行的时辰要求操纵数栈中最靠近栈顶的两个元素已经存入了两个int型的数值,当执行这个指令时,会将这两个int值和并相加,然后将相加的功效入栈。
操纵数栈中元素的数据范例必需与字节码指令的序列严酷匹配,在编译措施代码的时辰,编译器要严酷担保这一点,在类校验阶段的数据流说明中还要再次验证这一点。再以上面的iadd指令为例,这个指令用于整型数加法,它在执行时,最靠近栈顶的两个元素的数据范例必需为int型,不能呈现一个long和一个float行使iadd呼吁相加的环境。
2.3.1.1 动态链接
每个栈帧都包括一个指向运行时常量池中该栈帧所属要领的引用,持有这个引用是为了支持要领挪用进程中的动态毗连。我们知道Class文件的常量池有存有大量的标记引用,字节码中的要领挪用指令就以常量池中指向要领的标记引用为参数。这些标记引用一部门会在类加载阶段或第一次行使的时辰转化为直接引用,这种转化称为静态理会。其它一部门将在每一次的运行时代转化为直接引用,这部门称为动态毗连。
2.3.2 假造机栈的特点
2.3.3 假造机栈的非常
2.3.3.1 一种是StackOverflowError
当前列程假如哀求的栈深度大于假造机所应承的深度时,则会抛出该非常。譬喻,将一个函数重复递归本身,最终会呈现栈溢堕落误(StackOverflowError)。
代码清单如下:
- public class StackOverflowErrorDemo {
- public static void main(String []args){
- printStackOverflowError();
- }
- public static void printStackOverflowError(){
- printStackOverflowError();
- }
- }
输出非常功效:
- Exception in thread "main" java.lang.StackOverflowError
- stack length:9482
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
- at com.itech.jvm.demo.StackOverflowErrorDemo.printStackOverflowError(StackOverflowErrorDemo.java:22)
必要声名的是,在单个线程情形下,无论是栈帧太大,照旧假造机栈容量太小,当内存无法分派时,假造机城市抛出 StackOverflowError 非常。
2.3.3.2 一种是OOM非常
当假造机栈支持动态扩展时,假如无法申请到足够多的内存时就会抛出OOM非常。代码清单如下:
- public class VMOOMDemo {
- public static void main(String[] args) throws Throwable {
- VMOOMDemo demo = new VMOOMDemo();
- demo.printVMOOM();
- }
- public void printVMOOM() {
- while (true) {
- new Thread() {
- public void run() {
- while (true) {
- }
- }
- }.start();
- }
- }
- }
这个例子慎用... (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|