第二章(二) Java虚拟机结构-运行时数据区

2.5 运行时数据区域
    Java虚拟机定义了各种各样的运行时数据区,在程序执行过程中使用。这其中有些数据区域是在Java虚拟机启动时创建,只有在虚拟机结束时才被销毁。还有些数据区是各个线程的,线程的数据区在线程创建时创建,随线程的结束而销毁。
2.5.1 pc寄存器
    Java虚拟机支持许多线程同时执行。每一个线程都有自己的pc(程序寄存器)。在任意时点,一个线程只能执行一个方法,称为这个线程的当前方法。如果这个方法不是本地方法,pc寄存器中存放着当前执行着的虚拟机指令的地址;如果当前方法是本地方法,则pc寄存器是未定义的。Java虚拟机的pc寄存器足够大的可以存下一个returnAddress类型的值或者特定平台的本地指针。
2.5.2 Java虚拟机栈
    每个Java虚拟机线程都有一个自己Java虚拟机栈,在线程创建的时候创建。Java虚拟机栈存储栈帧,Java虚拟机栈可以类比于传统语言像C语言中的栈:它在方法调用和返回中用来,存储本地变量以及中间结果。Java虚拟机栈除了栈帧的出栈和进栈操作外不会被直接操作,栈帧有可能是从堆内存中分配的。Java虚拟机栈对应的存储区域不必是连续的。
    虚拟机规范中允许虚拟机栈即可以是固定大小的,也可以是根据运算需求可收缩的。如果Java虚拟机的大小是固定的,当栈创建时各个线程虚拟机栈的大小是可以独立指定的。
    Java虚拟机栈在以下情况下会出现异常
 

     
  • 线程在计算过程中需求的栈大小超出了允许值,虚拟机将抛出StackOverflowError.
  •  
  • 如果虚拟机栈设置的是可伸缩的,如果没有足够的内存来响应扩展,或者在线程船舰的时候,没有足够的内存来创建一个虚拟机栈,虚拟机将抛出OutOfMemoryError.
  •  

2.5.3 堆
    Java虚拟机有个堆存储区域,由所有的虚拟机线程共享。所有的类实例和数组都是从堆这个运行时数据区域中分配内存的。
    堆是在虚拟机启动时创建的。堆中存储的对象是通过自动存储管理系统(大家所熟知的垃圾回收机制)来进行回收的,对象不会显式的释放。Java虚拟机没有设定特定的自动存储管理系统,存储管理系统可以让虚拟机的实现者根据系统需要自动选择。堆得大小即可以是固定的也可以是可伸缩的,堆的存储区域不必是连续的。
    堆会在以下情况下出现异常
 

     
  • 当一个计算所需的堆空间大于存储管理系统可提供的大小时,虚拟机将抛出OutOfMemoryError.
  •  

2.5.4 方法区
    Java虚拟机有一个方法区,由所有的虚拟机线程共享。方法区可以类比于传统语言中编译后的代码的存储区域或者类比于操作系统中的文本段。它存储了每个类的结构,比如运行时常量池、字段、方法的数据、以及方法和构造器的代码包括类、实例、接口的初始化等特殊方法。
    方法区在Java虚拟机启动时创建。尽管方法区逻辑上是堆得一部分,简单的虚拟机实现中既不会对它用垃圾回收也不会压缩它。虚拟机规范既不要求方法区的位置,也不限定用来管理编译成的代码的策略。方法区的大小既可以是固定的也可以是可伸缩的。方法区的内存区域不必是连续的。
    方法区会在以下情况出现异常
 

     
  • 当方法区的内存不能满足一个内存分配的请求时,虚拟机将抛出OutOfMemoryError.
  •  

2.5.5 运行时常量池
    运行时常量池是一个类或者一个接口在类文件中的常量表的运行时的表示。包含几种类别的常量,例如在编译时代表方法和字段的数值字面值,这些值是必须在运行时决定具体指定的对象。运行时常量池的功能类似于传统编程语言中的符号表,但是它比符号表包含的范围更加广泛。
    所有的运行时常量池都是从虚拟机的方法区分配。一个类或接口的运行时常量池在这个类被虚拟机创建的时候构建。
   
  • 当创建一个类或接口时,如果构造常量池需求的内存空间大于Java虚拟机方法区能提供的内存大小时,虚拟机将抛出OutOfMemoryError.

2.5.6 本地方法栈
    Java虚拟机的实现者可能会用到传统意义的栈,通俗称为C栈,用来支持本地方法(用非Java语言编写的方法)。本地方法栈也可能用来在其他语言中来解释Java虚拟机的指令集,像C语言。虚拟机的实现者如果不需要加载本地方法,或者不需要传统意义的栈,则不必提供本地方法栈,如果提供的话,本地方法栈是随着每个线程创建而各自分配的。
    本地方法栈在以下情况出现异常
   
  • 如果一个线程的计算需要的本地方法栈大小超出了所允许的值,Java虚拟机将抛出StackOverflowError.
  • 如果本地方法栈能够自动扩展,而当自动扩展时没有足够的内存可用,或者没有足够的内存用来初始化一个新的线程的本地方法栈,虚拟机将抛出OutOfMemoryError.

猜你喜欢

转载自fengyilin.iteye.com/blog/2268559
今日推荐