Java虚拟机结构-运行时方法区

Java虚拟机结构-运行时数据区

  • PC寄存器
  • Java虚拟机栈
  • Java堆
  • 方法区
  • 运行时常量池
  • 本地方法栈

1. PC寄存器

Java虚拟机支持多线程同时运行,每条Java虚拟机线程有自己的PC寄存器

任意时刻,Java虚拟机线程只会执行一个方法的代码,该方法称为该线程的当前方法。

若该方法不是native的,则PC寄存器保存Java虚拟机正在执行的字节码指令的地址,如果方法是nativede,则PC寄存器的值是undefined。

2. Java虚拟机栈

每个Java虚拟机线程有自己私有的Java虚拟机栈,与线程同时创建,用于储存栈帧

用于存储局部变量和一些过程结果,以及方法的调用和返回。仅受栈帧的出栈和入栈影响,因此可在堆中分配。

Java虚拟机栈所使用的内存无需保证是连续的。

Java虚拟机栈可被实现为固定大小或者根据计算动态扩展和收缩。

若固定大小,则每一条线程的Java虚拟机栈容量应当在线程创建时独立的选定,Java虚拟机应提供程序员调节虚拟机栈初始容量的接口;

对于动态调节和收缩,则应当提供调节其最大、最小容量的手段

Java虚拟机栈可能发生如下异常:

  • 如果线程请求分配的栈容量超过Java虚拟机栈允许的最大容量时,Java虚拟机将会抛出一个StackOverflowError异常
  • 如果Java虚拟机栈可以动态扩展,并且扩展的动作已经尝试过,但目前无法申请到足够的内存,或创建新线程时没有足够的内存去创建对应的虚拟机栈,则Java虚拟机会抛出一个OutOfMemoryError异常

3. Java堆

在Java虚拟机中,堆(Heap)是可供各条线程共享的运行时内存区域,也是供所有类实例和数组对象分派内存的区域。

Java堆在虚拟机启动时被创建,存储了被自动内存管理系统(Automatic Storage Management System,即常说的"Garbage Collector(垃圾收集器)")所管理的对象(这些对象无需也无法被显式的销毁)。

自动内存管理技术-垃圾回收机制(不同虚拟机实现可能会使用不同的自动内存管理技术):引用计数(给对象中添加一个引用计数器,记录指向该对象的引用)和可达性分析(通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的)

GC Roots对象的选取

(1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。

(2). 方法区中的类静态属性引用的对象。

(3). 方法区中常量引用的对象。

(4). 本地方法栈中JNI(Native方法)引用的对象。

Java堆的容量可固定大小,也可动态扩展和收缩,所使用的内存空间可不连续。

对于动态调节和收缩,则应当提供调节其最大、最小容量的手段

Java堆可能发生如下异常: - 如果实际所需的堆超过了自动内存管理系统能提供的最大容量,那么Java虚拟机会抛出一个OutOfMemoryError异常

4. 方法区

可供各条线程共享的运行时内存区域。

类似于传统语言中的编译代码储存区或者操作系统进程的正文段。

储存每个类的结构信息,如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容,还包括一些在类、实例、接口初始化时用到的特殊方法。

方法区在虚拟机启动时被创建,容量可固定大小,也可动态扩展和收缩,在实际内存空间中可不连续。

对于动态调节和收缩,则应当提供调节其最大、最小容量的手段。

方法区可能发生如下异常:

  • 如果方法区的内存空间不能满足内存分配请求,那么Java虚拟机会抛出一个OutOfMemoryError异常

5. 运行时常量池

每个类或接口的常量池的运行时表现形式。

包含若干种常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。类似于传统语言中的符号表。

每一个运行时常量池都分配在Java虚拟机的方法区中,在类或接口被加载到虚拟机后,对应的运行时常量池就被创建。

在创建类和接口的运行时常量池时,可能会发生如下异常情况:

  • 当创建类或接口的时候,如果构造运行时常量池所需要的内存空间超过了方法区所能提供的最大值,那 Java 虚拟机将会抛出一个 OutOfMemoryError 异常。

6. 本地方法栈

Java虚拟机可能会使用传统的栈(C Stacks)来支持native方法(使用Java以外的其他语言编写的方法)的执行,即本地方法栈

若Java虚拟机不支持native方法,且不依赖传统栈,可不支持本地方法栈。如支持本地方法栈,本地方法栈一般会在线程创建时按线程分配

本地方法栈容量可固定大小或动态扩展和收缩。

固定大小时,每一条线程的本地方法栈容量应当在栈建立时独立的选定,需提供调节虚拟机栈初始容量的接口;动态扩展和收缩时,需提供调节其最大、最小容量的接口。

本地方法栈可能发生如下异常:

  • 如果线程请求分配的栈容量超过本地方法栈允许的最大容量时,Java虚拟机会抛出一个StackOverflowError异常。
  • 如果本地方法栈可动态扩展,且扩展的动作已经尝试过,但目前无法申请到足够的内存完成扩展,或者建立新线程时没有足够的内存创建对应的本地方法栈,Java虚拟机会抛出一个OutOfMemoryError异常。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值