[译] 一文了解 JVM

本贴最后更新于 1780 天前,其中的信息可能已经时移世异

原文地址:《The JVM Architecture Explained 》

每个 Java 开发者都知道字节码是被 JRE(Java 运行时环境)所执行的。但是许多人并不知道实际上 JRE 是 Java 虚拟机(JVM)的实现。它分析字节码,解释代码并执行它。作为一个开发者,了解 JVM 的体系结构是非常重要的,因为它使我们能更有效的编写代码。在这篇文章中,我们将更深入的了解 Java 中的 JVM 体系结构和 JVM 的不同组件。

什么是 JVM?

虚拟机是物理机器的软件实现。Java 语言当时是基于编写一次到处运行的理念被开发出来的,其中到处运行指的是运行在虚拟机上。编译器将 java 文件编译成.class 文件,然后.class 文件被输入到 JVM 中,JVM 会加载并运行这些.class 文件。下图展示了 JVM 的体系结构。

JVM 体系结构
JVMArchitecture.png

JVM 是如何工作的?

正如上图展示的,JVM 被分为以下三个主要的子系统:

  1. 类加载器
  2. 运行时数据区域
  3. 执行引擎

1.类加载器

Java 的动态类加载功能是由类加载子系统处理。它加载,链接,并初始化类(当在运行时第一次引用该类时)。

1.1 加载

类都通过该组件进行加载。BootStrap ClassLoader、 Extension ClassLoader、Application ClassLoader 这三个类加载器协同完成这个目标。

  • BootStrap ClassLoader:负责从引导类路径加载类,除了 rt.jar。将给予此加载程序最高优先级。
  • Extension ClassLoader:负责加载 ext 文件夹中的类。
  • Application ClassLoader:负责从应用程序类路径加载类。

以上这些类加载器将遵循双亲委托机制装载类文件。(即当一个类需要加载时,先从 Bootstrap 加载,没有的话,再从 Extension 加载,还是没有的话,才从 Application 加载。)

1.2 链接
  1. 验证:字节码验证器将会验证生成的字节码正确与否。如果验证失败,我们将得到验证错误信息。
  2. 准备:为所有静态变量开辟内存空间并赋默认值。
  3. 解析:将所有符号引用替换为方法区中的原始引用。
1.3 初始化

这是类加载的最后阶段。所有静态变量将会被赋予初始值并且静态构造块将会被执行。

2.运行时数据区

运行时数据区被分为五个主要的区域。

  1. 方法区:所有类级别的数据将会被存于此处。包括静态变量。一个虚拟机仅有一个方法区。它属于共享资源。
  2. 堆区:所有对象及对象中的实例变量和数组都将存于此处。一个虚拟机也仅有一个堆区。因为方法区和堆区在多线程情况下是共享内存的,所以存于其中的数据并非线程安全的。
  3. 虚拟机栈:对于每一个线程,都将创建一个单独的运行时方法栈。对于每一个方法调用,栈中都会生成一个栈帧。所有本地变量都将在栈中创建。栈区域是线程安全的,因为它并非共享资源。栈帧又被分为三个主要组成:
    1. 局部变量数组:与方法相关,涉及多少局部变量以及相应的值将存在这里。
    2. 操作数栈:如果需要执行任何中间操作,操作数栈充当运行时工作区来执行操作。
    3. 帧数据:与该方法对应的所有符号都存储在这里。在任何异常的情况下,catch 块信息将会保存在帧数据中。
  4. 程序计数器:每个线程都拥有独立的程序计数器。它保存当前执行指令的地址,一旦指令执行,程序计数器将更新为下一条指令。
  5. 本地方法栈:本地方法栈保存了本地方法调用信息。对于每一个线程,都会创建独立的本地方法栈。

3.执行引擎

分配到运行时数据区的字节码将会被执行引擎执行。执行引擎将会读取字节码并逐个执行。

  1. 解释器:解释器解释字节码快,但执行慢。并且在多次调用同一个方法时,都需要重新解释。

  2. JIT 编译器:JIT 编译器弥补了解释器的缺点。执行引擎会借助解释器去转换字节码。但是当它发现有重复的代码时,会使用 JIT 去编译整份字节码并将它改为本地代码。本地代码将会被直接使用在重复的方法调用,从而提高系统的性能。

    1. 中间代码生成器:生成中间代码
    2. 代码优化器:负责优化中间代码
    3. 目标代码生成器:负责生成机器码或本地代码
    4. 分析器:特殊组件,负责发现热点代码,即方法是否被多次调用。
  3. 垃圾回收器:回收和删除未被引用的对象。垃圾回收可被 System.gc()方法触发,但是不保证立马执行。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 7u

    阅读体验还不错。提个 bug:游客看文章,全篇加载 2 遍;但登录后恢复正常

  • someone
    作者

    收到!回头我跟 D 大反馈一下。哈哈。