JVM内存模型

JVM包含两个子系统和两个组件

  • 类装载子系统(Class loader)

根据给定的全限定名称将class文件加载到JVM内存,转为Class对象

  • 运行时数据区(Runtime data area)

即JVM的内存

  • 执行引擎 (Exception engine)

也叫解释器,负责解释命令,交由操作系统执行。执行classes中的指令

  • 本地库接口 (Native Interface)

本地接口的作用是融合不同的语言为java,所用是其他编程语言交互的接口

运行流程

(1)首先通过编译器把Java代码转换为字节码,类加载器(Class loader)再把字节码加载到内存中,将其放在运行时数据区(Runtime data area)的方法区中

(2)然后使用特定的命令解析器执行引擎 (Exception engine),将字节码翻译成底层系统指令。因为字节码文件只是JVM的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎将字节码翻译成底层系统指令。

(3)再将底层系统指令交由CPU去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

1 类装载子系统

JVM内存模型_第1张图片

1.1 四种类加载器

  • 启动类加载器 (Bootstrap 类加载器)

加载$JAVA_HOME/jre/lib/rt.jar里所有的class,不是ClassLoader子类

  • 扩展类加载器 (Extension 类加载器)

加载java平台中扩展功能的一些jar包,包括SJAVA_HOME/jre/lib/* .jar

或-Djava.ext.dirs指定目录下的jar包

  • 应用程序类加载器 (Application 类加载器)

加载classpath中指定的jar包及目录中class

  • Custom自定义类加载器

应用程序根据自身需要自定义的ClassLoader,如ltomcat、jboss都会根据j2ee规范自行实现ClassLoader。

1.2 类装载的执行过程

  • 加载:根据查找路径找到相应的class文件然后导入

  • 验证:字节码校验器会检生成的字节码是否正确,如果验证失败则会验证错误

  • 准备:对于所有静态变量的内存分配和默认值分配

  • 识别:解析或识别是从运行时常量池的符号引用中动态具体值的过程

  • 初始化:类或接口的初始化由执行类或接口初始化方法构成。这里所有的静态变量与原来的值将被指派,静态块将被执行

2 运行时数据区

结构图如下:

JVM内存模型_第2张图片
  • 方法区(Method Area)

存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

  • (Head 堆)

在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

存储的数据不是线程安全的,堆和常量空间不足则会引发OutOfMemoryError

  • 虚拟机栈(VM Statck)

每一个线程创建一个单独的运行时堆栈。对于每一个方法调用,一个称为栈内存栈帧被创建,所有局部变量将被创建在栈内存中。栈区域是线程安全的,因为它不是一个共享资源。

与程序计数器一样,JVM栈也是线程私有的,它的生命周期与线程相同。

栈空间用光了会引发StackOverflowError

  • 本地方法栈(Native Method Stack)

与虚拟机栈的作用是一样的,只不过虚拟机栈是服务java方法的,而本地方法栈是为虚拟机使用的 Native 方法服务

  • 程序计数器Program Counter Register

每个线程必须分开程序计数器登记,当前执行的指令一旦执行,程序计数器(程序计数登记器)更新下一个指令。一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。

3 执行引擎 (Exception engine)

通过类装载器装载的,被分配到VM的运行时数据区的字节码会被执行引擎执行。执行引擎以指令为单位读取Java字节码。它就像一个CPU一样,一条一条地执行机器指令。每个字节码指令都由一个1字节的操作码和附加的操作数组成。执行引擎取得个操作码,然后根据操作数来执行任务,完成后就继续执行下一条操作码。

你可能感兴趣的:(java知识点巩固,jvm)