JVM运行时数据区模型及说明
2018-08-11 16:19:10 31 举报
登录查看完整内容
JVM运行时数据区以及说明
作者其他创作
大纲/内容
Class文件的常量池中含有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用作为参数。这些符号引用一部分在每一次运行期间转化为直接引用,这部分称为动态链接。另外一部分是在类加载就确定了的直接引用,这种转化称为静态解析。
本地方法栈(JNI方法),线程共享
程序计数器(线程私有)
方法返回地址
堆中存放了new创建出的对象实例和数组,由各个线程共享。异常情况:如果堆中没有足够的内存来完成实例的分配,并且堆也无法再扩展时,抛出OOM
本地方法栈(JNI)
其他部分
Survivor(to)
方法区(线程共享)
永久代(jdk1.8以后已经被废弃,换成了元数据空间MetaSpace)
线程私有
java.lang.Class
问题:1.JVM的方法区是线程共享的,为什么在运行一个方法时却能做到线程隔离?答:JVM方法区存储的是方法、类以及其他信息,是一些静态数据,方法在运行时实际是在虚拟机栈中,虚拟机栈中包含很多栈帧,方法就是运行在栈帧里,并且JMM定义了每个线程有自己的缓冲(即TLAB),因此方法在运行时是线程隔离的。
JVM运行时数据区
栈帧3
假如整个数据运行区是个房子的话:1、虚拟机栈 - 为卧室(线程私有)2、程序计数器为卧室中的厕所(线程私有)3、方法区--厨房(线程共享)4、本地方法栈--衣帽间(线程共享,但只能放一些固定的东西)5、直接内存--阳台6、堆--客厅(啥都能放,而且空间最大)7、1.7中的永久代 -- 客厅中的餐厅(1.7中的永久代默认在堆中)8、1.8中的元空间 -- 车库(不算整体面积,算赠送)
操作数栈
LIFO
栈帧2
线程共享
局部变量表(max_locals确定了最大容量)
基本数据类型,对象的引用(reference),returnAddress
运行时常量池
存放了编译期生成的各种字面量和符号引用。受制于方法区内存大小。
直接内存(与IO操作相关)
虚拟机栈(线程私有)
堆(线程共享)
动态链接
指向运行时常量池的引用
Survivor(from)
附加信息
动态链接、方法返回地址、其他附加信息统称为附加信息
栈帧1
局部变量表中存放了基本数据类型,对象的引用,returnAddress。其中long和double类型占用两个局部变量空间(Slot),其余类型占用一个异常情况:1.线程请求的栈深度大于虚拟机允许的栈深度时,抛出SOF(StackOverFlow),典型调用:递归方法。2.虚拟机动态扩展时请求不到足够的内存时,抛出OOM
存放了编译期生成的各种字面量和符号引用。受制于方法区内存大小。异常情况:常量池无法再申请到内存时,抛出OOM
EdenEden区与survivor区默认比例为8:1:1
其余部分
程序计数器保证了线程间切换时的正确性,如:线程A切换到线程B后再切换到线程A,就是由程序计数器实现的。此区域是是唯一一个没有规定任何OutOfMemoryError 的区域
新生代(采用复制算法)
存储类信息(.class)、常量、静态变量、即时编译器编译后的代码等信息。java虚拟机规范中将方法区描述为堆的一个逻辑部分,但是他还有个别名叫Non-Heap(非堆),即与堆区分开来。异常情况:当方法区无法满足内存分配的需求时,抛出OOM
栈帧n
当方法开始执行时,操作数栈是空的。在方法执行过程中,会通过字节码指令向栈中pop或push数据(注意栈中存入的是数据具体值,而不是指令)。两种计算会用到操作数栈:1.算数运算。2.调用其他方法时,会通过操作数栈进行参数传递。
局部变量表
堆(线程共享)new创建出的对象实例和数组
老年代(根据收集器的不同选择不同的算法,一般为标记-整理算法)
默认年龄大于15
0 条评论
回复 删除
下一页