JVM虚拟机原理详解
本文旨在系统性的回顾JVM虚拟机原理,掌握JVM常用知识点及常见的面试考点,希望通过通俗易懂的思想进行学习,欢迎指正。文章目录
前言
JVM(Java Virtual Machine)是一种虚拟机规范,不同的厂商有自己的实现,使用最广的就是Oracle的HotSpot虚拟机,本文具体围绕HotSpot进行展开讲解,欢迎指正!第一章:概述
分析为何需要使用虚拟机?虚拟机带来的好处是什么?
1. 什么是JVM、JRE、JDK?
①. JVM(Java Virtual Machine:JAVA虚拟机)是指负责将字节码解释成为特定的机器码进行执行 的 “转换器(.class -> 机器码)”。Java源程序需要通过编译器编译为.class文件,才能被虚拟机加载、执行。(JVM = “字节码翻译执行器”:从软件层面屏蔽了不同操作系统在底层硬件与指令上的区别,达到了跨平台的特性。)
②. JRE是指Java运行时环境,也就是我们的写好的程序必须在拥有JRE的机器上才能运行。(JRE = JVM + JAVA核心类库-Lib + JAVA命令 + 基础构件)
③. JDK 是指Java开发人员所用的开发环境,包括常用的开发包、目的就是用来编译和调试Java程序的。(JDK = JRE + 编译器 + 其他类库-rt.jar)
2. 什么是平台无关性?(为什么要有虚拟机?)
①. 平台有关性:没有虚拟机,则所有的源代码需编译成可在本机操作系统运行的机器码(不同操作系统可执行的机器码不同),此时,该编程语言是平台有关性的!
②. 平台无关性:有了虚拟机,不同操作系统只用安装自己操作系统版本的JRE运行环境即可,通过编译器将java源程序(.java)编译成class字节码文件(class文件与操作系统和机器指令集无关),再由当前操作系统的JVM虚拟机读取、“翻译”成可在本地运行的机器码在不同的硬件上运行,此时,该编程语言是平台无关性的!
- 字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处运行”的关键所在!
3. 再来回顾:什么是JVM虚拟机?
JVM虚拟机通过软件的方式去模拟一个 具有完整硬件系统功能 且 能够运行在一个完全隔离环境 中的完整计算机系统,是一个虚构出来的计算机,是一种规范,是物理计算机的软件实现。
Java 虚拟机( JVM)是运行 Java 字节码的虚拟机,JVM 针对不同系统的有其特定的实现版本( Windows, Linux, macOS),目的是输入相同源代码编译后的字节码,不同的操作系统都会给出相同的执行结果,从而实现Java语言的跨平台特性!
4. 小结
虚拟机与操作系统进行交互(java -> class -> 机器码),再由操作系统与硬件交互(机器码 -> 控制硬件、资源,实现程序指令,完成功能)。从此以后,同一个功能,终于不用分别在不同的操作系统上实现其对应的版本了!
第二章:类加载机制
上章节提到,java源代码编译成class文件后,可由不同的JVM进行“翻译执行”,这说明,class文件中的信息,最终都要加载到虚拟机中才能运行和使用!
JVM将class字节文件加载到内存中,并进行校验、转换等,最终形成可被虚拟机直接使用的java类型的过程称为类加载! 即,将class文件加载到内存,并在方法区中开辟空间作为该类的Class对象,其中保存类种对应的运行时数据结构(类信息 + 常量池 + 静态变量 + 方法 …)!
1. 何时需加载? - 主动引用
(新生、反射、父亲、main)
①. 使用 new / getstatic / putstatic / invokestatic (实例化对象,读取设置类的静态字段,调用类的静态方法)时若该类未加载,则需加载相关的类!
②. 使用反射使用一个类时若未加载该类,则需加载相关的类!
③. 初始化一个类时,若其父类未初始化,需先初始化其父类!
④. 虚拟机启动时,需找到main()方法的类进行初始化!
2. 何时不加载? - 被动引用
(final、数组、static)
①. 若引用某个类中的final属性,则不需加载
②. 通过数组定义类的引用,不需初始化。eg:A[] a =