每个Java开发人员都知道字节码经由JRE(Java运行时环境)执行。但他们或许不知道JRE其实是由Java虚拟机(JVM)实现,JVM分析字节码,解释并执行它。作为开发人员,了解JVM的架构是非常重要的,因为它使我们能够编写出更高效的代码。本文中,我们将深入了解Java中的JVM架构和JVM的各个组件。

JVM

虚拟机是物理机的软件实现。Java的设计理念是WORA(Write Once Run Anywhere,一次编写随处运行)。编译器将Java文件编译为Java .class文件,然后将.class文件输入到JVM中,JVM执行类文件的加载和执行的操作。请看以下的JVM架构图:

JVM是如何工作的?

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

  1. 类加载器子系统(Class Loader Subsystem)
  2. 运行时数据区(Runtime Data Area)
  3. 执行引擎(Execution Engine)

1. 类加载器子系统

Java的动态类加载功能由类加载器子系统处理,处理过程包括加载和链接,并在类文件运行时,首次引用类时就开始实例化类文件,而不是在编译时进行。

1.1 加载

Boot Strap类加载器,Extension类加载器和Application(类加载器是实现类加载过程的三个类加载器。

(1) Boot Strap类加载器:负责从引导类路径加载类,除了rt.jar,它具有最高优先级;

(2) Extension 类加载器:负责加载ext文件夹(jre \ lib)中的类;

(3) Application类加载器:负责加载应用程序级类路径,环境变量中指定的路径等信息。

上面的类装载器在加载类文件时遵循委托层次算法(Delegation Hierarchy Algorithm)。

1.2 链接

(1) 验证(Verify):字节码验证器将验证生成的字节码是否正确,如果验证失败,将提示验证错误;

(2) 准备(Prepare):对于所有静态变量,内存将会以默认值进行分配;

(3) 解释(Resolve):有符号存储器引用都将替换为来自方法区(Method Area)的原始引用。

1.3 初始化

这是类加载的最后阶段,所有的静态变量都将被赋予原始值,并且静态区块将被执行。

2. 运行时数据区

运行时数据区可分为5个主要组件:

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

(2) 堆区域(Heap Area):所有对象及其对应的实例变量和数组将存储在这里。每个JVM也只有一个堆区域。由于方法和堆区域共享多个线程的内存,所存储的数据不是线程安全的;

(3) 堆栈区(Stack Area):对于每个线程,将创建单独的运行时堆栈。对于每个方法调用,将在堆栈存储器中产生一个条目,称为堆栈帧。所有局部变量将在堆栈内存中创建。堆栈区域是线程安全的,因为它不共享资源。堆栈框架分为三个子元素:

  • 局部变量数组(Local Variable Array):与方法相关,涉及局部变量,并在此存储相应的值
  • 操作数堆栈(Operand stack):如果需要执行任何中间操作,操作数堆栈将充当运行时工作空间来执行操作
  • 帧数据(Frame Data):对应于方法的所有符号存储在此处。在任何异常的情况下,捕获的区块信息将被保持在帧数据中;

(4) PC寄存器(PC Registers):每个线程都有单独的PC寄存器,用于保存当前执行指令的地址。一旦执行指令,PC寄存器将被下一条指令更新;

(5) 本地方法堆栈(Native Method stacks):本地方法堆栈保存本地方法信息。对于每个线程,将创建一个单独的本地方法堆栈。

3 执行引擎

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

(1) 解释器:解释器更快地解释字节码,但执行缓慢。解释器的缺点是当一个方法被调用多次时,每次都需要一个新的解释;

(2) JIT编译器:JIT编译器消除了解释器的缺点。执行引擎将在转换字节码时使用解释器的帮助,但是当它发现重复的代码时,将使用JIT编译器,它编译整个字节码并将其更改为本地代码。这个本地代码将直接用于重复的方法调用,这提高了系统的性能。JIT的构成组件为:

  • 中间代码生成器(Intermediate Code Generator):生成中间代码
  • 代码优化器(Code Optimizer):负责优化上面生成的中间代码
  • 目标代码生成器(Target Code Generator):负责生成机器代码或本地代码
  • 分析器(Profiler):一个特殊组件,负责查找热点,即该方法是否被多次调用;

(3) 垃圾收集器(Garbage Collector):收集和删除未引用的对象。可以通过调用“System.gc()”触发垃圾收集,但不能保证执行。JVM的垃圾回收对象是已创建的对象。

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

本地方法库(Native Method Libraries):它是执行引擎所需的本机库的集合。

转载自 http://geek.csdn.net/news/detail/131976

[转]一图读懂JVM架构解析的更多相关文章

  1. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的基本架构和工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的基本架构和工作机理 广东职业技术学院  欧浩源  ohy3686@foxmail.com Z-Stack协议栈是一个基于任务轮询方式的操作 ...

  2. 一张图读懂https加密协议

    搭建CA服务器和iis启用https:http://blog.csdn.net/dier4836/article/details/7719532 一张图读懂https加密协议 https是一种加密传输 ...

  3. 比传统事务快10倍?一张图读懂阿里云全局事务服务GTS

    近日,阿里云全局事务服务GTS正式上线,为微服务架构中的分布式事务提供一站式解决方案.GTS的原理是将分布式事务与具体业务分离,在平台层面开发通用的事务中间件GTS,由事务中间件协调各服务的调用一致性 ...

  4. 一图读懂k8s informer client-go

    概述 为什么要有k8s informer 我们都知道可以使用k8s的Clientset来获取所有的原生资源对象,那么怎么能持续的获取集群的所有资源对象,或监听集群的资源对象数据的变化呢?这里不需要轮询 ...

  5. 一张图读懂PBN飞越转弯衔接DF航段计算

    飞越转弯衔接TF航段时,转弯外边界与旁切转弯相似,只是在拐角位置直接以风螺旋绘制外边界,大部分切点可以精确计算得到. 飞越转弯衔接DF航段时,转弯外边界全部由风螺旋和它的切线构成,又会有哪些神奇的事情 ...

  6. 一张图读懂PBN飞越转弯衔接TF/CF航段计算

    在PBN旁切转弯的基础上,再来看飞越转弯接TF(或CF)航段,保护区结构上有些相似,只是转弯拐角处的保护区边界有“简化”,其余部分是相近的. FlyOver接TF段的标称航迹有一个飞越之后转弯切入航迹 ...

  7. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的核心思想与工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的核心思想与工作机理 广东职业技术学院  欧浩源   Z-Stack协议栈是一个基于任务轮询方式的操作系统,其任务调度和资源分配由操作系统抽 ...

  8. Java虚拟机系列一:一文搞懂 JVM 架构和运行时数据区

    前言 之前写博客一直比较随性,主题也很随意,就是想到什么写什么,对什么感兴趣就写什么.虽然写起来无拘无束,自在随意,但也带来了一些问题,每次写完一篇后就要去纠结下一篇到底写什么,看来选择太多也不是好事 ...

  9. 一文读懂JVM

    (一)JVM 基础知识 1)Java 是如何实现跨平台的? 注意:跨平台的是 Java 程序,而不是 JVM.JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本 ...

随机推荐

  1. event.currentTarget和event.target的区别

    currentTarget始终是监听事件者,而target是事件的真正发出者.

  2. Mypwd 的解读与实现 20155208

    Mypwd 的解读与实现 20155208 linux下pwd命令的编写 实验要求: 1 .学习pwd命令 2 . 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 .实现my ...

  3. day 017面向对象-反射

    主要内容: isinstance, type, issubclass( 内置函数) 区分函数和方法 反射 一    ( isinstance, type, issubclass) isinstance ...

  4. Docker第一个应用:Hello World

    Docker应用:Hello World 前言: 最近学习了Docker相关技术点,国内关于Docker的资料大多是基于Linux系统的,但是我对Linux又不熟(实际上没用过,掩面哭笑.Jpg). ...

  5. SSAS aggregation 的作用及其使用

    作用: 聚合是为了解决查询在运行时的效率低下,在数据立方体部署的时候进行聚合,实际上是对数据立方体的预处理,方便以后查询.如若在部署时未进行聚合,则在以后每次查询时实际上都会进行一次集合的操作,等待结 ...

  6. Python的函数基础

    引子 现在老板让你写一个监控程序,24小时全年无休的监控你们公司网站服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码 whi ...

  7. priority_queue的基本用法

    #include<bits/stdc++.h> using namespace std; int main() { ]; ;i<=;i++) a[i]=i; sort(a+,a++, ...

  8. python 面向对象(类的成员,属性,绑定和非绑定,)

    面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实 ...

  9. debezium mongodb 集成测试

    debezium 是一个方便的cdc connector 可以帮助我们解决好多数据实时变更处理.数据分析.微服务的数据通信 从上次跑简单demo到现在,这个工具是有好多的变更,添加了好多方便的功能,支 ...

  10. Benthos metrcis 说明

    Benthos 按照input, pipeline ,buffer,conditions,ouput 这个几个大类,为我们提供了 方便的分析metrics,支持json 格式同时可以暴露为 stats ...