本文是学习尚硅谷宋红康老师主讲的
尚硅谷JVM精讲与GC调优教程的总结 ,部分内容也参考了 JavaGuide 网站(文末有链接)
JVM 概述
-  Oracle JDK 与 OpenJDK 是什么关系? 2006 年 SUN 公司将 Java 开源,也就有了 OpenJDK。2009 年 Oracle 收购了 Sun 公司,于是在 OpenJDK 的基础上搞了一个 Oracle JDK。 - OpenJDK 网站:https://openjdk.org/projects/jdk/ ,仓库地址:https://github.com/openjdk/jdk/。Oracle JDK 网站:https://www.oracle.com/java/technologies/downloads/。
- OpenJDK 是完全开源且免费的。Oracle JDK 不是完全开源的,会提供免费版本,但一般有时间限制。
- 功能性上两者基本一致。
- OpenJDK 根据 GPL v2 协议获得许可,Oracle JDK 使用 BCL/OTN 协议获得许可。
 
-  JDK、JRE、JVM 是什么关系? JRE 包括 JVM 和 Java 基础类库,JDK 不仅包含 JRE,还包括编译器 javac 和其他工具,如 javadoc(文档生成器)、jdb(调试器)、jconsole(监控工具)、javap(反编译工具) 等。 不过,从 JDK 9 开始,就不需要区分 JDK 和 JRE 的关系了,取而代之的是模块系统和 jlink 工具。 
-  常见的 JVM 有哪些? HotSpot、JRockit、J9 
-  JIT 是什么? 
 JIT 是 Just In Time 的缩写,JVM 将字节码文件转换为机器码时,JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。后面引进了 JIT 编译器,当 JIT 编译器完成第一次编译后,将字节码文件中的热点代码对应的机器码保存下来,下次可以直接使用。
-  JVM 架构图 
   
字节码文件概述
-  生成 class 文件的编译器有哪些? 也叫前端编译器,有javac、ECJ(Eclipse Compiler for Java,是一种增量式编译器)、ajc(AspectJ编译器)。 
-  javac 编译器的编译步骤有哪些? 词法分析、语法分析、语义分析、生成字节码。 
-  如何解读 class 文件? -  查看二进制工具:Notepad++ 安装 HEX-Editor 插件,或者 Binary Viewer软件。 
-  使用 Oracle 官方的反解析工具 javap javap -v xxx.class
-  使用IDEA插件:jclasslib 或 jclasslib bytecode viewer 客户端工具。 
 
-  
class 文件结构
-  class 文件结果有哪几部分? - 魔鬼数字: 0xCAFEBABE
- class 文件版本
- 常量池
- 访问标识
- 类索引、父类索引、接口索引集合
- 字段表集合
- 方法表集合
- 属性表集合
 官网文档:https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html  
-  JDK 1.1 对应的 class 文件版本是 45 ,后面版本依次加 1 。虚拟机JDK版本为1.k (k >= 2)时,对应的class文件格式版本号的范围为45 - 44 + k 。 
-  常量池 常量池存放所有常量。常量池表项中,用于存放编译时期生成的各种 - 字面量 - 文本字符串
- 声明为 final 的常量值
 
- 符号引用 - 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
 
 
- 字面量 
字节码指令
Java 虚拟机的指令由一个字节长度的操作码和操作数构成,指令集的操作码总数不超过 256 条。
官方文档: https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-6.html
JVM 中字节码的指令集按用途大致分为 9 类:
- 加载与存储指令,如 xload、xstore等
- 算术指令,如 iadd、isub 等
- 类型转换指令,如 i2l、l2f 等
- 对象的创建与访问指令,如 new、 getstatic、getfield 等
- 方法调用与返回指令,如 invokevirtual、ireturn 等
- 操作数栈管理指令,如 pop、dup 等
- 控制转移指令,如 ifeq、iflt 等
- 异常处理指令,如 athrow
- 同步控制指令,如 monitorenter、monitorexit
Java 虚拟机还有一个只在内部使用的基本类型:returnAddress ,Java 程序员不能使用这个类型,这个基本类型被用来实现 Java 程序中的 finally 子句。该类型是 jsr、ret 以及 jsr_w 指令需要使用到的,它的值是 JVM 指令的操作码指针。 returnAddress 类型不是简单意义的数值,不属于任何一种基本类型,并且它的值是不能被运行中的程序所修改的。
参考
- 尚硅谷JVM精讲与GC调优教程 (宋红康主讲) (https://www.bilibili.com/video/BV1Dz4y1A7FB?spm_id_from=333.788.videopod.episodes&vd_source=9266b9af652d5902d068c94b9d60116f)
 M精讲与GC调优教程 (宋红康主讲) (https://www.bilibili.com/video/BV1Dz4y1A7FB?spm_id_from=333.788.videopod.episodes&vd_source=9266b9af652d5902d068c94b9d60116f)
- JavaGuide网站 (https://javaguide.cn/java/basis/java-basic-questions-01.html)