课程地址
https://time.geekbang.org/column/article/11289
1.Java代码是怎么运行的
内容总结
字节码是啥?
编译器将 Java 程序转换成该虚拟机所能识别的指令序列,也称 Java 字节码。
之所以这么取名,是因为 Java 字节码指令的操作码(opcode)被固定为一个字节。jvm如何工作的?
从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。
加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。
Java 虚拟机会将栈细分为面向 Java 方法的 Java 方法栈,面向本地方法(用 C++ 写的 native 方法)
的本地方法栈,以及存放各个线程执行位置的 PC 寄存器。
在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。
例题
观察两个条件判断语句的运行结果,来思考 Java 语言和 Java 虚拟机看待 boolean 类型的方式是否不同。
Foo.java
1
2
3
4
5
6
7public class Foo {
public static void main(String[] args) {
boolean flag = true;
if (flag) System.out.println("Hello, Java!");
if (flag == true) System.out.println("Hello, JVM!");
}
}编译并运行
1
2
3
4$ javac Foo.java #将Foo.java编译为Foo.class(16进制的字节码文件)
$ java Foo #jvm执行Foo.class文件
Hello, Java!
Hello, JVM!基于asmtools将Foo.class转换成可编辑的文本文件
1
$ java -cp ~/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm
修改asm中iconst_1值
1
2
3$ awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Foo.jasm.1 > Foo.jasm
$ java -cp ~/asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm
$ java Foo
1 | lixldeMacBook-Air:demo lixl$ cat Foo.jasm.1 |