JVM基本组成(持续更新JVM),详细

本文详细阐述了Java虚拟机(JVM)的组成,包括其在Java编程中的关键角色,如字节码、类加载器、垃圾收集器和跨平台性。文章还涵盖了JDK与JRE的区别,以及Java的编译和执行过程,强调了性能优化和内存管理的重要性。

JVM基本组成

为什么要学习JVM

​ 学习Java虚拟机(Java Virtual Machine)是为了深入理解和有效使用Java语言进行编程。JVM是Java平台的关键组成部分,负责将Java源代码翻译成可在不同平台上运行的字节码。

  1. 跨平台性: JVM的存在使得Java程序具有跨平台的能力。Java程序只需在一种平台上编写一次,然后可以在任何支持Java的平台上运行,而无需重新编写或修改。这种能力得益于JVM将Java源代码编译成中间字节码,然后在不同平台上解释执行。
  2. 性能优化: JVM实现了即时编译(Just-In-Time Compilation,JIT),它将字节码在运行时编译成本地机器代码,从而提高程序的性能。学习JVM有助于理解这一过程,以便能够优化Java程序的性能。
  3. 内存管理: JVM负责Java程序的内存管理,包括内存分配、垃圾回收等。了解JVM的内存模型和垃圾回收机制有助于编写更加健壮和高效的Java程序,并避免内存泄漏等问题。
  4. 调优和故障排除: 学习JVM使你能够更好地理解Java应用程序在运行时的行为,帮助你进行性能调优和解决潜在的问题。你可以使用不同的工具和选项来监控和调整JVM的行为,以满足应用程序的需求。
  5. 类加载机制: JVM的类加载机制是Java语言的核心之一。理解类加载机制有助于深入理解Java程序的执行过程,包括类的加载、链接和初始化。
  6. 安全性: JVM提供了一种安全的执行环境,可以在其中运行Java应用程序,防止恶意代码的执行。学习JVM有助于理解Java的安全性特性,包括类加载器的作用和沙箱机制。
  7. 面试和职业发展: 对JVM的深入了解是Java开发者的一项重要技能。在面试中,对JVM的理解可能是一个加分项,而在职业发展中,深厚的Java技能和对JVM的了解可能使你在团队中更具竞争力。

JDK\JVM\JRE

  1. JDK(Java Development Kit):
    • 定义: JDK是Java开发工具包,它是Java软件开发的完整工具集合。它包括了JVM、Java类库以及编译、调试等开发工具。
    • 组成:
      • JVM: Java虚拟机,用于在计算机上运行Java程序。
      • Java类库: Java标准类库(Java Standard Edition,Java SE)包含了大量的类和方法,用于各种应用程序开发。
      • 开发工具: 编译器(javac)、调试器(jdb)、Java文档生成器(Javadoc)等。
    • 用途: JDK是开发者在创建、编译和调试Java应用程序时所需的工具。如果你希望进行Java开发,你需要安装JDK。
  2. JVM(Java Virtual Machine):
    • 定义: JVM是Java虚拟机的缩写,是Java程序运行的虚拟计算机。它负责将Java源代码编译成字节码,并在计算机上执行这些字节码,如果不需要编写Java代码而只需要运行Java代码只需要有JVM即可。
    • 功能:
      • 解释字节码:JVM可以将Java源代码编译成字节码,并通过解释器将字节码翻译成机器码,实现跨平台性。
      • 即时编译:JVM还可以使用即时编译器(JIT)将字节码直接编译成本地机器码,提高程序的执行效率。
      • 垃圾回收:JVM负责自动管理内存,包括垃圾回收和内存分配。
    • 用途: JVM是Java程序的运行环境,它使Java程序具有跨平台性和自动内存管理的特性。
  3. JRE(Java Runtime Environment):
    • 定义: JRE是Java运行时环境的缩写,它包含了JVM和Java类库,但不包括开发工具。
    • 组成:
      • JVM: Java虚拟机,用于运行Java程序。
      • Java类库: Java标准类库,提供了各种Java程序所需的类和方法。
    • 用途: JRE主要用于运行Java应用程序。如果你只是希望运行Java程序而不是进行开发,你只需安装JRE。

三者之间的关系:

  • JDK包含JRE: JDK是更大的集成开发环境,它包括JRE,同时还包含了开发工具,适用于Java的开发人员。
  • JRE包含JVM: JRE提供了Java运行时环境,其中包含了JVM,以便能够运行Java程序。

用一张图表示三者之间的关系:

在这里插入图片描述

Java的执行过程

在初始接触Java编程时都有一个经历就是用记事本写Java代码,然后用cmd命令行进行运行。有两个步骤:

  1. 编译:通过javac命令,调用JDK编译器,将xxx.java源文件编译成xxx.class字节码文件
  2. 执行:通过java命令,调用JVM虚拟机,执行xxx.class文件。
    在这里插入图片描述

Java程序的跨平台

​ Java特性之一就是跨平台性,但是具体什么是平台?通常把CPU处理器与操作系统构成的系统架构,称为计算机平台。

​ 现代的电子计算机是基于二进制设计实现,所以CPU 仅能识别0与1这样的二进制信号。而计算机程序的本质就是0与1之间的不同组合产生的机器指令,交给CPU去执行。CPU为了能识别执行机器指令,就需要不同CPU架构和指令集来支持。不同的厂商,设计生产的CPU ,CPU架构和指令集也是不同的。

​ 常见的指令集主要分为:精简指令集(RISC)和复杂指令集(CISC )。

  • 复杂指令集(CISC) : X86 和X64两种CPu 架构基于CISC复杂指令集,比如:Intel 、AMD等厂商的CPU。
  • 精简指令集(RISC ) :ARM架构的CPU基于RISC精简指令集,比如: Compa的Alpha 、HP的PA-RISC 、IBM 的Power PC .Apple的M1。

​ 在底层硬件及指令集之上,需要搭载不同的操作系统,用于支持不同的CPU 指令集。例如:早期的MacOS操作系统只支持Power系列的CPU。最新的MacOS系统只能安装在M1芯片的CPU。Java是一种跨平台的编程语言,主要是为了让相同的Java应用程序代码,不用做任何修改,可以在不同计算机系统平台上正常运行,兼容各种主流操作系统+CPU 指令集。

​ Java是一种跨平台的编程语言,主要是为了让相同的Java代码,不做任何的修改,可以在任何不同计算机系统系统上正常运行,兼容各种主流的操作系统和CPU指令集。

在这里插入图片描述

静态编译器

通过JDK提供的静态编译器,将Java 源文件编译成字节码文件。
编译过程包括:

1.词法分析:通过空格分隔出源代码中的单词、操作符、控制符等信息,将其形成 token 信息流,传递给语法解析器。

2.语法分析:将token信息流按照Java语法规则,组装成一颗语法树

3.语义分析:对语法树进行关键字使用、类型匹配、作用域等语法检查。

4.字节码:当语义分析完成后,可以生成字节码。

在这里插入图片描述

字节码

​ 当一个Java源文件被编译后,就会按照JVM规范和字节码定义,产生1个class字节码文件,文件内容由10个固定部分组成。

​ 前4个字节非常特殊,其中1~2字节为cafe babe是詹姆斯高斯林定义的魔法数,他的作用是标志当前文件是一个字节码文件,当JVM进行类的加载的Load阶段时,如果没有识别到该标志,就说明不是字节码文件或者被损坏的字节码文件,因此无法进行加载。3~4字节代表当前的版本号,0x34的十进制为52,是JDK8的内部版本号,代表这个字节码五年间基于JDK8编译。

​ 剩余部分中的每个字节均代表一个字节码指令,由于每个指令的长度按照1个字节存储,所以每个指令被称为字节码( Bytecode ) , Java所有的字节码指令有200多个。由于纯数字的字节码指令阅读比较困难,所以JVM在字节码指令的基础上设计了一套操作码助记符,使用特殊单词来代替对应的数字指令。

​ 0x15 ILOAD:读取int类型的局部变量

​ 0x36ISTORE:保存int类型的局部变量

​ 0x60 IADD :执行两个int类型的数值加法运算

​ 0xbb NEW:创建对象

​ 0xbc NEWARRAY:创建数组

​ 0xac IRETURN:返回int类型结果

在这里插入图片描述

JVM执行方式

JVM以解释+编译混合模式,执行字节码文件。

  1. JVM的执行方式以解释执行为主。执行过程中,JVM将每个字节码文件中的每个指令,通过解释器转换成当前平台可以识别的机器码,然后交给CPU 执行。
  2. 为了提高执行效率,JVM还会在运行期间,JVM通过热点代码的统计分析,识别高频的方法调用,循环体、公共模块等,当超过阈值时,JVM会基于JIT时编译器( just-in-time compiler)将热点代码转换成机器码,直接交给CPU执行,提高执行效率。
    • client模式下默认阈值是1500次,在Server模式下是10000次。

JVM解释器:程序执行的时候,解释器首先发挥作用,省去了编译器编译时间,加快程序的执行效率。
JIT编译器:在程序运行过程中,随着时间的推移,JIT开始慢慢发挥了作用,把热点代码编译成本地代码后,以后执行相同的代码,即可直接交给CPU执行,带来更高的执行效率。

在这里插入图片描述

​ 机器在热机状态可以承受的负载要大于冷机状态(刚启动时),如果以热机状态时的流量进行切换,可能使处于冷机状态的服务器因无法承载流量而假死。所以,在生产环境中发布应用,应该以分批的方进行发布,根据机器数量划分成多个批次,每个批次的机器数大概占到整个集群的15%。

​ 故障案例:某应用在线发布新版本,采用进行分批发布,发布总批数误填写成分为两批发布。如果是热机状态,正常情况下,集群中的一半的机器可以勉强支撑负载流量,但由于刚启动的JVM均是解释执行,还没有进行热点代码统计和JIT动态编译,导致机器启动之后,当前1/2发布成功的服务器马上全部宕机。

类加载器

​ 字节码必须通过类加载器,通过加载、验证、解析等校验步骤,将字节码文件中的类,加载至JVM的中运行时数据区,才可以执行字节码。

在这里插入图片描述

垃圾收集器

​ JVM在运行期间,通过Garbage Collctor垃圾收集器,定期对运行时数据区进行垃圾对象的回收,从而实现了内存自动管理。

JVM组成结构

​ JVM由类加载器、运行时数据区、JVM解释器、JIT即时编译器、垃圾回收器、本地方法库等部分组成。

​ 由类加载器完成字节码文件的加载验证和解析,存储至运行时数据区,并由执行引擎中的解释器,完成字节码到机器码的解释执行。同时进行热点代码的统计分析,调用JIT即时编译器将字节码直接编译成机器码,提高执行效率。JVM运行期间的方法调、数据对象统一存放至运行时数据区。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值