JVM(一)JVM与Java体系结构

JVM与Java体系结构

Java是目前应用最广泛的软件开发平台之一,是一门跨平台的语言,write once,runanyWhere。Java程序编译为字节码文件之后,可以被各个平台的JVM解释运行。

image-20221212121849474

而JVM则是跨语言的平台,不仅仅支持java语言,其他提供的字节码文件符合jvm规范的语言也能被jvm所解释运行。

image-20221212122447282

1 前置知识

image-20221212113345652
字节码与混合编程

java字节码,指的是java语言编译成的字节码,任何能在jvm平台上运行的字节码格式都是一样的,所以应该统称为jvm字节码。Java虚拟机与Java语言没有必然的联系,它只与特定的二进制文件格式class文件有关系,class文件包含了Java虚拟机指令集(字节码、ByteCodes)符号表其他的一些辅助信息

多语言混合编程,指的是使用特定领域的语言去解决特定领域的问题,运行在同一个虚拟机上的语言可以进行交互使用,就像调用自己语言的原生API一样方便。

虚拟机

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

  • 系统虚拟机:对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。如VMWare、Virtual Box等。
  • 程序虚拟机:专门为执行单个计算机程序而设计,如Java虚拟机,在Java虚拟机中执行的指令成为Java字节码。

无论是系统还是程序虚拟机,上面运行的软件都被限制于虚拟机提供的资源中。

Java虚拟机 Java Virtual Machine
  • Java虚拟机就是一台执行Java字节码文件的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码文件也不一定由Java语言编写。
  • JVM平台的各种语言都能够共享Java虚拟机带来的跨平台性、优秀的垃圾回收机制,以及可靠的即时编译器。
  • Java技术的核心就是Java虚拟机,所有的Java程序都是运行在JVM里面的。
JVM的特点
  • 一次编译,到处运行
  • 自动的内存管理
  • 自动垃圾回收机制
Java虚拟机的作用

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

2 JVM的整体结构

image-20221212170302147

整体流程是前端编译器将java程序编译为字节码文件,然后通过类加载子系统(Class Loader)将字节码文件变为一个Class对象加载到内存,内存中的运行时数据区分为方法区(Method Area)堆(Heap),和Java栈本地方法栈程序计数器,其中方法区和堆是多线程共享的,其他的是线程私有的。加载到内存后,会由执行引擎的后端编译器将字节码文件编译为计算机识别的机器指令进行执行。

image-20221212171629185

上图是一张JVM体系结构的详细图,其中执行引擎又细分为后端编译器、JIT编译器(用于处理热点代码、即时编译)以及垃圾回收器。

Java代码的执行流程
image-20221212171937815

​ Java的内存区域主要包含类加载子系统运行时数据区执行引擎运行时数据区又分为方法区、堆、程序计数器、虚拟机栈和本地方法栈,java代码的执行流程为:6

  • 首先由javac前端编译器将源代码编译为字节码文件,然后由类加载子系统对字节码文件进行加载、链接和初始化后在内存的运行时数据区方法区中生成一个Class对象,作为访问类的数据的入口
  • 类的加载完成之后,就需要创建类对应的对象,主要是为对象在中分配内存空间,并对分配到的空间进行初始化操作
  • 在实际的运行过程中,对象调用的每一个方法都对应一个栈帧栈帧能够进行入栈、出栈操作,栈帧中保存着方法执行过程中需要的各种数据
  • 然后执行引擎就会先从程序计数器中获取当前栈帧中的地址对应的字节码指令,将其翻译成CPU能够执行的机器指令后,再结合当前栈帧中存储的方法需要的数据进行相应的操作,最后弹出栈帧完成方法的执行并更新程序计数器中下一条需要执行的字节码指令
JVM的架构模型
  • 基于栈的指令集架构

    • 设计实现简单、适合资源受限的系统
    • 避开了寄存器分配难题,使用零地址指令分配,执行依赖于操作栈,指令集更小,但是指令多,编译器容易实现
    • 不需要硬件支持,可移植性好,更好实现跨平台
  • 基于寄存器的指令集架构:

    • 完全依赖硬件,可移植性差
    • 性能优秀,执行更高效

    Android的Davlik虚拟机就是选择的基于寄存器的指令集架构

    第一种零地址以8位进行对齐,而第二种是16位,所以基于栈的指令集架构的指令集更小

    HotSpotVM使用的是基于栈的指令集架构

JVM的生命周期

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

虚拟机的执行:程序执行的时候虚拟机就会执行,程序结束的时候虚拟机就会停止。执行Java程序的时候,实际上是Java虚拟机的进程在执行这个程序。

虚拟机的退出:有以下几种情况:

  1. 程序正常执行结束
  2. 程序在执行过程中遇到了异常或错误而异常终止
  3. 操作系统出现错误而导致JVM终止
  4. 线程调用Runtime、System类的exit方法,或Runtime类的halt方法,并且Java安全管理器也允许这次halt或exit方法
虚拟机的种类
Classic VM

Classic VM是Sun公司发布的世界上第一款java虚拟机,在JDK1.4的时候被完全淘汰了。这款虚拟机只提供解释器,想要使用即时编译器的话需要进行外挂,现在HotSpot虚拟机内置了此虚拟机。

一旦使用了JIT虚拟机,就会接管虚拟机的执行系统,解释器就不能工作了,因此二者是不能同时工作的。

image-20221212181925893

即时编译器JIT在编译的时候会先去查找热点代码进行编译为机器指令,然后将其缓存到方法区中的CodeCache;而解释器则是逐行去解释字节码文件为机器指令,解析器的缺点显而易见,逐行解释导致性能较差,比如一个for循环重复执行还是会去逐行编译,但是完全使用JIT也不可取,编译字节码文件上来就全部缓存到方法区中会消耗一定的时间,导致暂停时间过长影响运行。

Exact VM

为了解决上一个虚拟机存在的问题,Sun公司在jdk1.2提出了Exact VM。

  • Exact Memory Management:精准内存管理,即虚拟机可以知道内存中的某个位置的数据是什么类型的。
  • 具备现代高性能虚拟机的雏形:
    • 热点探测
    • 编译器与解释器混合工作

明确内存中某个位置的数据的类型,指的是该数据是实际的数据还是引用类型的数据(即存放的对象的地址),比如垃圾回收后判断数据不是垃圾,如果是对象的引用则需要改变对象的地址。

☆HotSpot

JDK1.3的时候,HotSpot成为默认的虚拟机,拥有GC机制(其他的两个虚拟机都没有方法区的概念),并且在服务器、桌面到移动端、嵌入式都有应用。

HotSpot即热点探测技术:

  • 通过计数器找到最具编译价值的代码,触发的时候进行即时编译或者栈上替换
  • 通过编译器与解释器的协同工作,在最优化的程序响应时间最佳的执行性能中取得平衡
JRockit

BEA的JRokit虚拟机专注于服务器端的应用,因此不太关注应用的启动速度,内部不包含解释器,代码完全靠即时编译器编译后执行。JRockitJVM是世界上最快的JVM。

优势:全面的Java运行时解决方案。

  • JRockit面向延迟敏感型应用的解决方案JRockit Real Time提供以毫秒级、微秒级的JVM响应时间,适合财务、军事指挥、电信网络的需要。
  • MissionControl服务套件,它是以一组极低的开销来监控、管理和分析生产环境的应用程序的工具。
J9

IBM的J9,和前两个是目前三大最具有影响力的商用虚拟机。可以应用于服务器端、桌面端和移动端,也号称是最快的虚拟机,被广泛用于IBM的Java产品。

KVM CDC/CLDC HotSpot
Azul VM Liquid VM
image-20221212190652062 image-20221212190852490

3 内存结构概述

image-20221212191546256

类加载子系统:加载字节码文件到内存,然后在方法区存放生成问答最大的class对象,同时对静态的属性做一些初始化

方法区:用于存放类的信息、常量、域信息和方法信息(三大虚拟机HotSpot虚拟机独有

:创建的java对象都分配在堆区,堆区是线程共享的,也是垃圾回收机制重点考虑的空间,是使用的内存最大的地方

如果自己手写一个虚拟机,主要考虑类加载器子系统执行引擎

posted @ 2023-05-17 18:55  Tod4  阅读(174)  评论(0编辑  收藏  举报