跳过正文
  1. 文章/
  2. Java/
  3. JVM/
  4. 内存与垃圾回收/

1、JVM和Java体系结构

·1800 字·4 分钟· loading · loading · ·
Java JVM 内存与垃圾回收
GradyYoung
作者
GradyYoung
内存与垃圾回收 - 点击查看当前系列文章
§ 1、JVM和Java体系结构 「 当前文章 」

JVM
#

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的

引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(.class二进制字节码文件),就可以在多种平台上不加修改地运行

JVM还是一个跨语言的平台,除了java语言,很多语言都可以在JVM上进行运行,只有遵守JVM规范,使用自己的编译器生成.class字节码文件

image-20220228220331600

也就是说,JVM只关心字节码文件,并不关心该字节码文件是由什么语言编译的

JVM的位置
#

image-20220228223647493

JVM的整体结构
#

HotSpot虚拟机是目前市面上高性能虚拟机的代表之一,采用解释器和即使编译器共存的架构

image-20220228223947549

image-20220302154334001

类装载器子系统:主要负责将每个字节码文件加载到内存中,生成Class对象,涉及加载、链接等过程

运行时数据区:内存中的主要结构,方法区和堆区是多线程共用的,其余的虚拟机栈、本地方法栈、程序计数器是每个线程都有一份

执行引擎:主要包括解释器、JIT及时编译器(编译器的后端,编译.java的编译器成为前端编译器)、垃圾回收器

JVM的架构模型
#

Java编译器输入的指令流基本是基于栈的指令集架构;还有一种指令集架构就是基于寄存器的指令集架构

  • 基于栈的架构
    • 设计和实现更简单,适用于资源受限的系统
    • 避开了寄存器的分配难题,使用零地址指令方式分配
    • 指令流中的指令大部分是零地址指令,其执行过程依赖操作栈,指令集更小,编译器更容易实现
    • 不需要硬件支持,可移植性更好,更好实现跨平台
  • 基于寄存器的架构
    • 典型应用是x86的二进制指令集,比如传统的PC以及Android的Davlik虚拟机
    • 指令集架构则完全依赖硬件,可移植性差
    • 性能优秀和执行更高效
    • 花费更少的指令去完成一项操作
    • 大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主

例如,同样执行2+3的操作:

基于栈

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

基于寄存器

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

反编译java文件就可以看到,java是基于栈的内存指令

public class Demo {	
	public static void main(String[] args) {
		int i = 2;
		int j = 3;
		int k = i + j;
	}	
}

使用javap -v Demo.class命令对生成的字节码文件进行反编译

image-20220228232356321

JVM的声明周期
#

虚拟机的启动
#

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

虚拟机的执行
#

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

虚拟机的退出
#

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

常见的JVM
#

Sun Classic VM
#

java1.0时发布,java1.4被淘汰

是世界上第一款商用的Java虚拟机

现在默认使用的Hotspot虚拟机内置了Sun Classic VM

虚拟机内部只提供了解释器,而现在主流的JVM都是解释器+JIT编译器(即时编译器)

Exact VM
#

java1.2提供此虚拟机

Exact Memory Management:准确式内存管理,虚拟机可以知道内存某个位置的数据具体是什么类型

具有现代高性能虚拟机的雏形:热点特测、编译器和解释器混合工作,被Hotspot虚拟机替换

HotSpot VM(默认)
#

三大高性能虚拟机之一

java1.3成为默认虚拟机

HotSpot这个名字就是指它的热点代码探测技术

JRockit
#

三大高性能虚拟机之一

专注于服务器端应用,不在乎应用的启动速度,所以不包含解释器,全部代码都使用即时编译器编译后执行

是世界上最快的JVM

由BEA开发,现在已经被Oracle收购,Oracle大致在JDK8完成和HotSpot整合

J9
#

三大高性能虚拟机之一

IBM开发

市场定位和HotSpot接近,服务器端、桌面应用、嵌入式等

内存与垃圾回收 - 点击查看当前系列文章
§ 1、JVM和Java体系结构 「 当前文章 」