目录
一 jvm整体结构
主要由 程序计数器,本地方法栈,堆,虚拟机栈,方法区 等组成,其中堆和方法区属于线程共享,其他的为线程隔离。
官方文档地址:Chapter 2. The Structure of the Java Virtual Machine
程序计数器
英文名:The pc Register;Java虚拟机可以支持多个线程同时执行。每个Java虚拟机线程都有自己的pc(程序计数器)寄存器。在任何时候,每个Java Virtual Machine线程都在执行单个方法的代码,即该线程的当前方法。如果该方法不是本机的,则pc寄存器包含当前正在执行的Java虚拟机指令的地址。如果线程当前正在执行的方法是本机的,则Java虚拟机的pc寄存器的值是未定义的。Java虚拟机的pc寄存器足够宽,可以在特定平台上保存一个returnAddress或本机指针。
本地方法栈
Java 虚拟机的实现可以使用传统的堆栈,通俗地称为“C 堆栈”,以支持native
方法(用 Java 编程语言以外的语言编写的方法)。本地方法堆栈也可以由 Java 虚拟机指令集的解释器实现使用,例如 C 语言。无法加载native
方法且本身不依赖常规堆栈的Java 虚拟机实现不需要提供本机方法堆栈. 如果提供,则通常在创建每个线程时为每个线程分配本机方法堆栈。
该规范允许本地方法堆栈具有固定大小或根据计算需要动态扩展和收缩。如果本机方法堆栈的大小是固定的,则在创建该堆栈时可以独立选择每个本机方法堆栈的大小。
Java 虚拟机实现可以让程序员或用户控制本地方法堆栈的初始大小,以及在可变大小的本地方法堆栈的情况下,控制最大和最小方法堆栈大小。
注意:
如果线程中的计算需要比允许的更大的本机方法堆栈,则 Java 虚拟机将抛出StackOverflowError
.
如果可以动态扩展本机方法堆栈并尝试扩展本机方法堆栈但可以提供足够的内存,或者如果可以提供足够的内存来为新线程创建初始本机方法堆栈,则 Java 虚拟机将抛出OutOfMemoryError
.
堆(heep)
Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的堆。堆是运行时数据区,从中分配所有类实例和数组的内存。
堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会被显式释放。Java 虚拟机不假设任何特定类型的自动存储管理系统,存储管理技术可以根据实现者的系统需求来选择。堆可以是固定大小的,也可以根据计算的需要进行扩展,如果不需要更大的堆,则可以收缩。堆的内存不需要是连续的:分为 规整和不规整两种。
Java 虚拟机实现可以为程序员或用户提供对堆初始大小的控制,以及如果堆可以动态扩展或收缩,则可以控制最大和最小堆大小。
以下异常情况与堆相关联:
如果计算需要的堆多于自动存储管理系统所能提供的堆,Java 虚拟机将抛出一个 OutOfMemoryError.
新生代和老生代
虚拟机栈
每个 Java 虚拟机线程都有一个私有的Java 虚拟机堆栈,与线程同时创建。Java 虚拟机堆栈存储帧。Java 虚拟机堆栈类似于 C 等传统语言的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。因为除了推送和弹出帧之外,Java 虚拟机堆栈从不直接操作,所以内存可能被分配到堆上。Java 虚拟机堆栈的内存不需要是连续的。
在第一版中的Java ®虚拟机规范,Java虚拟机堆被称为Java堆栈。该规范允许 Java 虚拟机堆栈具有固定大小或根据计算需要动态扩展和收缩。如果 Java 虚拟机堆栈的大小是固定的,那么在创建该堆栈时可以独立选择每个 Java 虚拟机堆栈的大小。
Java 虚拟机实现可以为程序员或用户提供对 Java 虚拟机堆栈初始大小的控制,以及在动态扩展或收缩 Java 虚拟机堆栈的情况下,控制最大和最小大小。
以下异常情况与 Java 虚拟机堆栈相关联:
如果线程中的计算需要比允许的更大的 Java 虚拟机堆栈,则 Java 虚拟机会抛出一个StackOverflowError.
如果 Java 虚拟机堆栈可以动态扩展,并且尝试扩展但没有足够的内存来实现扩展,或者如果没有足够的内存可以为新线程创建初始 Java 虚拟机堆栈,则 Java 虚拟机机器抛出一个OutOfMemoryError.
方法区
Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的方法区。方法区类似于传统语言的编译代码存储区,或类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类和实例初始化和接口初始化中使用的特殊方法。
方法区是在虚拟机启动时创建的。尽管方法区在逻辑上是堆的一部分,但简单的实现可能会选择不进行垃圾收集或压缩它。本规范不强制要求方法区的位置或用于管理编译代码的策略。方法区可以是固定大小,也可以根据计算的需要进行扩展,如果不需要较大的方法区,可以缩小。方法区的内存不需要是连续的。
Java 虚拟机实现可以为程序员或用户提供对方法区初始大小的控制,以及在可变大小方法区的情况下,对最大和最小方法区大小的控制。
以下异常条件与方法区相关联:
如果方法区中的内存不能用于满足分配请求,Java 虚拟机将抛出一个OutOfMemoryError.