从=JVM虚拟机结构=中学习堆栈

来源:互联网 发布:制图软件photoshop 编辑:程序博客网 时间:2024/05/05 12:20

栈(Stack)


 JVM={JVM-Thread1,JVM-Thread2,JVM-Thread3,..,..,..,JVM-ThreadN}
一个虚拟机有多个虚拟机线程,每一条线程创建的时候都会得到一个虚拟机栈,用于存储栈帧
栈帧用于存储局部变量与一些还没有计算好的结果。
栈除了在栈帧出入栈外,不会再受到其他因素影响

栈帧

存储局部变量,过程结果,返回值,异常分派,动态链接
栈帧随着方法调用而创建,随方法结束而销毁。异常和正常完成的方法都算作方法结束
栈帧的存储空间由创建他的线程,在虚拟机栈中分配。
栈帧【本地变量表、操作数栈、当前栈帧所指向的方法的常量池的引用 】
只有正在执行的栈帧是活动的,成他为当前栈帧,其对应的方法为当前方法,其类为当前类,对局部变量表和操作数栈的都是针对于当前栈帧内的二者。
栈帧是当前线程的,无法引用另一个线程的栈帧。

局部变量表

存储类或接口的二进制表示,提供给栈帧使用
一个局部变量可以保存short,float,int,char,boolean,byte,char,referece(引用类型),returnAddress(指向一条虚拟机操作码)
两个局部变量可以保存long,double

首个局部变量从0开始索引,[0,长度]
例: [val1,val2,val3,val4]
         [0     ,     1,     2,     3]
long double占用2个连续的局部变量表索引,并采用较小的一个索引来定位(n与n+1)。n+1虽然无法用于读取,但是有可能被写入,写入后n的数据也将失效破坏了完整性
例:[long_val,doble_val]
        [0,1          ,2,3]

操作数栈

LIFO(后进先出)栈,jvm从局部变量表或对象实例的字段中将一些常量变量复制到操作数栈,也提供了一些指令来从操作数栈中提取数据,操作数据,数据重新入栈等操作。
操作数栈也可以用来调用方法或接受结果
例:
      栈顶 1,2
      执行iadd指令
      1,2出栈
      1+2 = 3
      3入栈
指令要与数据匹配 2个long数据用iadd指令是无法完成的


动态链接

将class文件中符号引用转化为直接引用。

异常

线程请求分配的栈容量超过虚拟机允许的最大容量,则抛出StackOverflowError 栈溢出异常
如果虚拟机支持栈动态扩展,在尝试扩展时或在创建一个新的线程时没有足够内存去创建相应的栈,则会抛出OurOfMemoryError 堆溢出

堆(Heap)


实例,数组,对象所在区域
堆中内容被垃圾回收器所管理
堆的大小可以是固定的,也可以是动态调整的,这取决于我们的设置

异常

如果堆超过了最大容量将会抛出OutofMemoryError 堆溢出

方法区

提供了各个线程共享的运行时内存区域。
他存储了每个类的结构信息,常量池,构造,方法数据的字节码信息
方法区在JVM启动时随之创建,虽然方法区是堆的逻辑组成,方法区也可以选择动态或固定的空间调整

异常

如果方法区空间不满足内存分配要求也会抛出OutOfMemoryError异常 堆溢出

运行时常量池

class中类,接口运行时的常量池表的表示形式
包含了从编译期即得到的常量到运行期解析后才能得到的方法或引用。
他属于方法区中,在创建类和接口的运行常量池时可能会抛出

异常

常量池超过了方法区提供的最大值OutOfMemoryError  堆溢出


本地方法栈(native Stack)


使用传统的C stack来支持native方法,这就是本地方法栈
当虚拟机使用其他语言来实现指令解释时,也会调用本地方法栈
如果虚拟机不支持native或不依赖传统栈,那么本地方法栈不被依赖
如果支持,则此栈会在线程创建时按线程分配
本地方法栈支持动态和固定配置

异常

超过栈最大容量则 StackOverflowError
本地方法栈如动态扩展,无法申请到足够内存则OutofMemoryError

原创粉丝点击