JVMG
字节码就是 Java 编译出来的类似汇编的以 .class 为后缀的文件。
Java语言是一门解释性语言。
对操作数进行操作,所以引入了栈,用户模拟原来方法帧的 C帧中的栈帧,栈帧要存储数据,
操作码+操作数
常量池存在的意义:用于保存hashmap。
在编译阶段,对于一些变量,还没有加载到内存,因此不知道变量的地址,因此引入常量池,所以用一个符号,当作 hashmap的key,当将其装载到 jvm 之后,就可以通过 key 拿到其真实的 value 的引用,然后将其取过来。
符号解析:把hashMap 的value用真实地址替换
代表了下标为 2 的常量池里的内容。内容里描述了属性信息
操作数栈:用于存储指令后的操作数
public class HelloWorld { public static void main(String[] args) { int a=1; a++; } }
Classfile /D:/HelloWorld.class Last modified 2022-10-1; size 278 bytes MD5 checksum a457b0a2ddacecbd6a9f8e242022dfc1 Compiled from "HelloWorld.java" public class HelloWorld minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #3.#12 // java/lang/Object."<init>":()V #2 = Class #13 // HelloWorld #3 = Class #14 // java/lang/Object #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LineNumberTable #8 = Utf8 main #9 = Utf8 ([Ljava/lang/String;)V #10 = Utf8 SourceFile #11 = Utf8 HelloWorld.java #12 = NameAndType #4:#5 // "<init>":()V #13 = Utf8 HelloWorld #14 = Utf8 java/lang/Object { public HelloWorld(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: iconst_1 //将操作数栈1取出 1: istore_1 //存入局部变量表1 2: iinc 1, 1//局部变量表自增指令 5: return LineNumberTable: line 3: 0 line 4: 2 line 5: 5 }
movl $1 -4(%ebp) addl $1 -4(%ebp)
操作数栈到局部变量表。
计算机中寄存器,栈空间, JVM没有,因此用局部变量表替换(数组)
CISC RISC
RISC 编译器压力大。
指令正交
@CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }
方法里面有方法帧,方法帧里有指向常量池的指针。
通过方法帧指向常量池的指针,拿到Class。

浙公网安备 33010602011771号