每个Java开发人员都知道字节码将由JRE (Java运行时环境)执行。但是很多人不知道JRE是Java Virtual Machine(JVM)的实现,它分析字节码、解释代码并执行代码。作为开发者,了解JVM的体系结构非常重要,因为它使我们能够更有效地编写代码。在本文中,我们将更深入地了解Java中的JVM体系结构和JVM的不同组件。

什么是JVM呢?

虚拟机是物理机的软件实现。Java是用WORA(编写一次运行到任何地方)的概念开发的,它在VM上运行。编译器将Java文件编译成Java .class文件,然后将.class文件输入JVM, JVM加载并执行类文件。下面是JVM的架构图。

JVM是如何工作的?

如图所示,JVM分为三个主要子系统:

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

1. 类加载器子系统

Java的动态类加载功能由类加载器子系统处理。它装载的链接。在运行时而不是编译时首次引用类时初始化类文件。

1.1 加载

类将由该组件加载。引导类加载器、扩展类加载器和应用程序类加载器是有助于实现这一目标的三个类加载器。

  1. 引导类加载器 – 负责从引导类路径加载类,除了rt.jar什么也没有。这个加载程序将获得最高优先级。
  2. 扩展类加载器 – 负责加载ext文件夹(jre\lib)中的类。
  3. 应用程序类加载器 –负责加载应用程序级类路径、所述环境变量的路径等。

上述类加载器在加载类文件时将遵循委托层次结构算法。

1.2 链接

  1. 验证 – 字节码验证器将验证生成的字节码是否正确,如果验证失败,我们将得到验证错误。
  2. 准备 – 内存将为所有静态变量分配默认值。
  3. 解析 – 所有符号内存引用将被来自方法区域的原始引用所替换。

1.3 初始化

这是类加载的最后阶段;在这里,所有静态变量都将被赋初始值,并且静态块也会被执行。

2. 运行时数据区

运行时数据区被分为五个主要组件:

  1. 方法区 – 所有类级数据都将存储在这里,包括静态变量。每个JVM只有一个方法区,它是资源共享的。

  2. –所有对象及其对应的实例变量和数组都将存储在这里。每个JVM也仅有一个堆。由于方法区和堆被多个线程共享内存,因此存储的数据不是线程安全的。

  3. –每个线程将创建一个单独的运行时栈。每个方法调用都会在栈内存中生成一个条目,称为栈帧。所有本地变量都将在栈内存中创建。栈区域是线程安全的,因为它不是内存共享的。

    栈区域被分为三个部分:

    1. 局部变量数组 – 与方法相关,涉及到局部变量以及相应的值都将存储在这里。
    2. 操作数堆栈 –如果需要执行任何中间操作,操作数堆栈充当运行时工作区来执行操作。
    3. 帧数据 – 所有与方法对应的符号都存储在这里。在任何异常情况下,catch块信息都将保存在帧数据中。
  4. PC寄存器 – 每个线程将有单独的PC寄存器,以保持当前执行指令的地址一旦指令执行,PC寄存器能顺利地更新到下一条指令。

  5. 本地方法栈 – 本机方法栈保存着本地方法信息。对于每个线程,都将创建一个单独的本机方法栈。

3. 执行引擎

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

  1. 解释器 – 解释器更快地解释字节码,但执行速度很慢。解释器的缺点是,当一个方法被多次调用时,每次都需要一个新的解释。

  2. JIT编译器

    – JIT编译器消除了解释器的缺点。执行引擎将在转换字节码时使用解释器的帮助,但是当它发现重复的代码时,它使用JIT编译器,JIT编译整个字节码并将其更改为本机代码。此本机代码将直接用于重复的方法调用,从而提高系统的性能。

    1. 中间代码生成器 – 生成中间代码
    2. 代码优化器 – 负责优化上面生成的中间代码
    3. 目标代码生成器 – 负责生成机器代码或本地代码
    4. 分析器 – 一个特殊的组件,负责寻找热点,即方法是否被多次调用。
  3. 垃圾收集器:收集和删除未引用的对象。可以通过调用 System.gc()触发垃圾收集,但不能保证执行。JVM的垃圾收集收集创建的对象。

Java本地接口(JNI): JNI将与本地方法库交互,并提供执行引擎所需的本地库。

本机方法库: 这是执行引擎所需的本机库的集合。

最初发表于2016年9月

进一步的阅读

Java Memory Management

A Detailed Breakdown of the JVM

The Evolution of the Java Memory Architecture


8月福利准时来袭,关注公众号

后台回复:003即可领取7月翻译集锦哦~

往期福利回复:001,002即可领取!

JVM体系结构详解的更多相关文章

  1. [转]JVM指令详解(上)

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码    助记符      ...

  2. Linux内核异常处理体系结构详解(一)【转】

    转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...

  3. JVM内存详解-阅读笔记

  4. JVM结构详解

    JVM 结构详解 JVM 结构图 程序计数器(PC 寄存器) 程序计数器的定义 程序计数器是一块较小的内存空间,是当前线程正在执行的那条字节码指令的地址.若当前线程正在执行的是一个本地方法,那么此时程 ...

  5. Android OS体系结构详解

    Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统.中间件.用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件. 架构详解 下 ...

  6. Oracle体系结构详解

    对于一门技术的学习,尤其是像Oracle database这种知识体系极其庞杂的技术来讲,从宏观上了解其体系结构是至关重要的.同时,个人认为,未必是专业DBA人员才需要了解其体系结构(固然对于数据库专 ...

  7. 一篇看懂JVM底层详解,利用class反编译文件了解文件执行流程

    JVM之内存结构详解 JVM内存结构 java虚拟机在执行程序的过程中会将内存划分为不同的区域,具体如图1-1所示. 五个区域 JVM分为五个区域:堆.虚拟机栈.本地方法栈.方法区(元空间).程序计数 ...

  8. JVM组成详解

    一.JVM 整体组成 JVM 整体组成可分为以下四个部分: 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库 ...

  9. java异常体系结构详解

    前几天在参加网易和360公司的在线考试的时候,都出了一道关于java中异常类的多项选择题.这几天翻看了相关书籍和网上一些资料,结合自己的理解与思考,将自己的一些收获记录如下: 先来看看java中异常的 ...

随机推荐

  1. hdu第十场Cyclic

    本题主要是对用容斥的使用,正难则反,对于要求满足题意的可以求不满足题意的 先考虑对于长度至少为2的连续序列,易得其排列C(n,1)*(n-2)!,意为从剩下n个数字中选取连续的两个. 方法总计为n,即 ...

  2. 在Linux - Centos上安装Python3(上)

    必看内容 在Linux上安装Python常用的2种方法 1.Python源码编译安装,有点复杂,适合老司机 2.从EPEL/IUS仓库安装,新手建议使用些方法,比较简单,目前2019-07-31提供最 ...

  3. Spring中FactoryBean的作用和实现原理

    BeanFactory与FactoryBean,相信很多刚翻看Spring源码的同学跟我一样很好奇这俩货怎么长得这么像,分别都是干啥用的.BeanFactory是Spring中Bean工厂的顶层接口, ...

  4. Linux下zookeeper下载与安装教程

    原文连接:(http://www.studyshare.cn/blog-front//blog/details/1169/0)一.下载 官网下载:点这里  百度网盘下载:点这里 官网下载图示: jav ...

  5. 全开源C++ DirectUI 界面库SOUI 3.0更新

    从2019.5.22开始,SOUI版本号更新到2.9.0.2,后面开始准备3.0的开发,历时近3个月,现在3.0的主要工作基本完成. 为了便于大家区别2.x,3.0启用了新的代码仓库:https:// ...

  6. 深入理解JVM-java字节码文件结构剖析(1)

    public class MyTest1 { private int a = 1; public int getA() { return a; } public void setA(int a) { ...

  7. html的一些基本语法学习与实战

    其实在学校前端开始之前,问过自己为什么要学,因为自己学的比较杂,直到现在刚刚毕业出来工作了,才明确了方向了,要往嵌入式方向走,但是随着时代的发展,在编程和智能硬件结合的越来越紧密,特别是物联网这一块, ...

  8. 【一些小常识】Linux文件目录的通配符用法/*

    在使用linux命令的时候,一时有点搞不清*的用法,于是整理记录下,在做jenkins 持续集成时还是很有用的 “*”在通配符中是最常用的一种,主要整理下在使用Linux命令时,文件夹目录的用法. 1 ...

  9. Activiti 开发案例之动态指派任务

    流程图 以上是一个请假的流程图,以下为流程任务节点描述: 员工发起请假流程 部门经理审批 同意则进入人事审批 拒绝则调整申请或者直接结束流程 人事审批通过则进入销假环节 人事审批拒绝则调整申请或者直接 ...

  10. C#使用WebClient调用接口

    用于上传图片base64位 private void upLoadCunzai() { errorstring += " upLoadCunzai方法执行成功:用于上传已经存在人员摄像头照片 ...