JVM1 JVM与Java体系结构

JVM与Java体系结构

虚拟机与Java虚拟机

虚拟机

虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。

VMware就属于系统虚拟机,它们完全是对物理计算机硬件的仿真(模拟),提供了一个可运行完整操作系统的软件平台。
程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。

Java虚拟机

Java虚拟机是一台执行Java字节码的虚拟计算机,现在JVM跨语言平台,不光能解释Java字节码,准确的说任何能在jvm平台上执行的字节码格式(其他语言编译的字节码)都是一样的。所以应该统称为Jvm字节码

JVM平台的各种语言可以共享Java虚拟机带来的

  • 跨平台性
  • 优秀的垃圾回器
  • 以及可靠的即时编译器

Java技术的核心就是Java虚拟机(JVM,Java Virtual Machine),因为所有的Java程序都运行在Java虚拟机内部。

作用:
Java虚拟机是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。

特点:

  • 一次编译,到处运行(字节码文件)
  • 自动内存管理
  • 自动垃圾回收功能

JVM的位置

JVM是运行在操作系统之上的,它与硬件没有直接的交互

image

JDK(Java Development Kit) Java开发工具包:是提供给Java开发人员使用,其中包含了java的开发工具与JRE --> JDK = JRE + 开发工具集(如编译器javac.exe,java.exe,javadoc.exe)

JRE(Java Runtime Environment) Java运行环境:包括java虚拟机和java程序所需的核心类库等,如果想要运行一个开发好的Java程序,只需要JRE即可 --> JRE = JVM + Java SE标准类库

image

JVM的整体结构

image

类加载器子系统:将编译好的.Class文件加载到JVM中
运行时数据区:存储在JVM运行过程中产生的数据,包括程序计数器、方法区、本地方法去、虚拟机栈和虚拟机堆
执行引擎:即时编译器将Java字节码编译成具体的机器码,垃圾回收器回收在运行过程中不再使用的对象
本地接口库:用于调用操作系统的本地方法库完成具体的指令操作。

Java代码执行流程

image

主流编译器采用解释执行与编译执行并存的方式

解释器:保证响应时间
编译器:字节码中的热点(反复执行)指令直接编译成机器指令缓存,保证执行性能

1.Java源文件(.java)被编译器编译成字节码文件(.class)
2.JVM将字节码文件编译成相应操作系统的机器码
3.机器码调用相应操作系统的本地方法库执行相应的方法

Java跨平台的原因

每个操作系统的解释器都是不同的,但基于解释器实现的虚拟机时相同的

JVM的架构模型

Java编译器输入的指令流基本上是一种基于栈的指令集架构,因为跨平台性的设计,另外一种指令集架构则是基于寄存器的指令集架构

基于栈的指令级架构

基于栈式架构的特点:
设计和实现更简单,适用于资源受限的系统;
避开了寄存器的分配难题:使用零地址指令方式分配
指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现
不需要硬件支持,可移植性更好,更好实现跨平台

栈:跨平台性、指令集小、指令多,执行性能比寄存器差

基于寄存器的指令级架构

基于寄存器架构的特点:
典型的应用是x86的二进制指令集:比如传统的PC以及Android的Davlik虚拟机。
指令集架构则完全依赖硬件,与硬件的耦合度高(指令直接由CPU执行),可移植性差
性能优秀和执行更高效
花费更少的指令去完成一项操作
在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主

两种架构的举例

同样执行2+3这种逻辑操作,其指令分别如下:

基于栈的计算流程(以Java虚拟机为例):

iconst_2 //常量2入栈
istore_1
iconst_3 // 常量3入栈
istore_2
iload_1
iload_2
iadd //常量2/3出栈,执行相加
istore_0 // 结果5入栈

8个指令

而基于寄存器的计算流程

mov eax,2 //将eax寄存器的值设为1
add eax,3 //使eax寄存器的值加3

2个指令

JVM的生命周期

在一个Java进程开始运行后,虚拟机就开始实例化了,有多个进程启动就会实例化多个虚拟机实例。进程退出或者关闭,则虚拟机实例消亡,虚拟机实例之间不能共享数据。

虚拟机的启动

Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。

类加载器的作用

  1. 类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问接口。
  2. 类缓存:某个类被加载到类加载器中,它将维持加载(缓存)一段时间。

自定义类加载器 -> 系统类加载器 -> 扩展类加载器 -> 引导类加载器
系统类加载器AppClassLoader:自己定义的类
扩展类加载器:负责jre(Java Runtime Environment)/lib/ext目录下的jar包或
引导类加载器(bootstrap class loader):负责java平台核心库的加载,该加载器无法直接获取。无法加载自定义类。

虚拟机的执行

一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序
程序开始执行时他才运行,程序结束时他就停止
执行一个所谓的Java程序的时候,真真正正在执行的是Java虚拟机进程

虚拟机的退出

有如下的几种情况:

程序正常执行结束
程序在执行过程中遇到了异常或错误而异常终止
由于操作系统用现错误而导致Java虚拟机进程终止
某线程调用Runtime类或System类的exit()方法,或Runtime类的halt()方法,并且Java安全管理器也允许这次exit()或halt()操作。

posted @ 2021-11-10 16:55  rananie  阅读(39)  评论(0编辑  收藏  举报