秉承一个信念,要学遍学底层逻辑。那是一通百通的底气。
一、学不学JVM 是自主解决问题的一流程序员与跟着别人做CRUD的二流程序员的分水岭。只有深入了解透彻jvm的工作过程及原理,才能对自己开发出高性能的代码充满信心。
二、JVM虚拟机的本质:将class文件转换成操作系统具体的指令。
一个java文件从编写到执行的过程:通过javac将java文件编译成一个class文件交给虚拟机,虚拟机的工作过程如图:

1首先就是将classFile文件通过类加载(ClassLoader也就是个类)加载到jvm虚拟机的内存中。就是将类加载到就是方法区(元数据区)
2然后交给执行引擎,将类中指令解析出来执行,执行过程中会将类创建对象。
3再将对象创建到堆当中。
那要执行某个东西需要一个逻辑就是线程。因为只有线程是执行程序的唯一单元。在jvm内部,会对每一个线程分配一个虚拟机栈(左数第2列),它是一个先进后出的栈结构。在这个栈里面会记录当前线程运行的所需要的数据。
虚拟机栈(线程私有)核心包括:
栈帧(会为每个方法创建一个专属的内存空间 ),栈帧又包含:
局部变量表:存放每个方法里的局部变量
操作数栈:这两个是执行java文件最基础的数据结构,记录我要执行这个方法需要多少的内存。局部变量对应的操作数。
动态链接库:是指向方法区的哪个方法
返回地址(方法出口):执行完返回到哪里
附加信息:jvm自己实现时附带的信息。
程序计数器:记录当前线程运行到哪一步了。
二、Class 文件规范
1、Class文件结构
实际上,我们需要了解的是,Java 官方实际上只定义了JVM的一种执行规范,也就是class文件的组织规范。理论上,只要你能够写出一个符合标准的class文件,就可以丢到 JVM 中执行。至于这个class文件是怎么来的,JVM 虚拟机是不管的。这也是 JVM 支持多语言的基础。
比如,对于一个ByteCodeInterView.class文件,可以用 UltraEdit 工具打开一个class文件,看到的内容部分是这样的:

中间这一部分就是他的二进制内容。当然这是十六进制的表达。空格隔开的部分代表了 8 个bit,而每一位代表的是 4 个 bit字节,也就是一个十六进制的数字。例如 第一个字母 C 就表示十六进制的 12,二进制是 1100。而所有的class文件,都必须以十六进制的 CAFEBABE 开头,这就是 JVM 规范的一部分。这也解释了 Java 这个词的由来,到底是一种咖啡,还是爪哇岛。
Spring6及springboot3已经用到jdk17了,但是我们jdk8 是跑不起来spring6的。
后面的部分就比较复杂了,没法直接看。可以用 javap指令可以直接来看一些class文件。比如:

还是不容易查看或看懂,可以安装并使用插件:jclasslib Bytecode viewer图形化查看:

可以看到jvm的字节码,以及整个的执行过程:



再就是LineNumbertable这里,说明第10行代码执行的 0到6的指令。
