龙岗建设网站,优秀 响应式网站,西安机场商务宾馆百度做网站,怎样设计网站首页文章目录 4.JVM的运行时数据区4.1 程序计数器4.2 Java虚拟机栈4.3 虚拟机栈内存溢出 4.JVM的运行时数据区
4.1 程序计数器
程序计数器#xff08;PC#xff09;会记录着下一行字节码指令的地址。执行完当前指令后#xff0c;PC刷新#xff0c;JVM的执行引擎根据程序计数器… 文章目录 4.JVM的运行时数据区4.1 程序计数器4.2 Java虚拟机栈4.3 虚拟机栈内存溢出 4.JVM的运行时数据区
4.1 程序计数器
程序计数器PC会记录着下一行字节码指令的地址。执行完当前指令后PC刷新JVM的执行引擎根据程序计数器执行下一行指令。
在多线程环境下Java虚拟机需要通过程序计数器记录CPU切换前解释执行到哪一句指令并继续解释执行。 4.2 Java虚拟机栈
Java虚拟机栈使用栈的数据结构来管理方法调用中的基本数据。每一个方法的调用使用一个栈帧Stack Frame来进行保存。方法调用就入栈方法结束就出栈。程序一开始的时候虚拟机栈是空的程序结束的时候虚拟机栈也是空的。
Java虚拟机栈随着线程的创建而创建回收会在线程的销毁时执行由于方法可能可能会在不同线程中执行所以每个线程都有自己的虚拟机栈。
栈帧是如何组成的 局部变量表
栈帧中的局部变量表是一个数组数组中的每一个位置称为槽。long和double类型占用两个槽其他类型包括引用类型占用一个槽。
局部变量表保存的内容有实例方法的this对象方法的参数方法体中声明的局部变量。按照顺序进行保存。
对于字节码文件来说其局部变量表的信息就很详细。记录了每个变量的编号第几个变量PC开始位置以及长度其实就是作用域PC可以访问多长的位置超过这个长度就不能使用这个变量了在数组中的索引序号变量的名字。 操作数栈和帧数据
操作数栈在编译期就可以确定操作数栈的最大深度从而在执行时正确地分配内存大小。
帧数据在不同的虚拟机中有不同的内容。不过有一些核心内容是一样的。比如动态链接、方法出口、异常表的使用。
动态链接当前类的字节码指令引用了其他类的属性或者方法时需要将符号引用编号转换成对应的运行时常量池中的内存地址动态链接就保存了编号到运行时常量池的内存地址的映射关系。所以动态链接保存了映射关系。
方法出口方法结束时当前栈帧会从虚拟机栈中弹出同时PC应该指向上一个栈帧中下一条指令的地址所以当前栈帧中需要保存此方法出口的地址。
异常表存放代码中异常的处理信息包含了try代码块和catch代码块执行后跳转到的字节码指令位置。
Java中还有一类方法是由c/c实现的称为本地方法。这些方法会放在哪里呢 4.3 虚拟机栈内存溢出
当栈帧的数量过多内存占用超过了虚拟机栈的默认内存大小就会出现栈内存溢出StackOverflow。最典型的场景——无限递归就会导致栈内存溢出。
栈具有默认大小win中虚拟机栈大小不同的系统可能会不同。 可以通过-Xss这个参数来设置虚拟机栈的大小。 显然栈帧中局部变量过多会引起局部变量表过大操作数栈深度变大也会影响一个栈帧的大小从而影响虚拟机栈能够存放栈帧的个数。但是一般情况下栈帧都不会达到几千个所以可以手动把虚拟机栈内存调小点节省内存。