理解JVM-字节码

字节码是jvm语言,java 不是。

jvm 的语言

字节码是jvm 的语言。jvm 可以通过翻译字节码来执行指令。 那么任何一门语言如果可以翻译为字节码,那么就可以使用jvm来执行。 字节码作为一种中立的计算机治理表示方式,为众多的语言在jvm 上执行提供了可能。

Java 语言和字节码

我们可以通过javac (java编译器)将java翻译成字节码。从某种程度上来说java 和jvm 没有直接的联系,如果把java 直接翻译为机器码,那么java 的执行就不用依赖于jvm了。 java 是一种计算机语言,提供了一种现实世界到计算机世界的抽象表达方式。 最终怎么执行,依赖于编译器。我们可以使用javac 来编译java代码,也可以使用gcc。
既可以将java 代码编译为class(字节码), 也可以编译为机器语言( jit做的就是这件事情)。

对字节码名字的理解

计算机通过执行指令,来实现制定的操作。 指令可以被抽象成由两部分组成,操作码( opcode) 和 操作数( operand)。 操作吗理解为要执行的动作, 操作数理解为执行动作需要的参与者。 例如给计算机加电, 操作码是加电操作,操作数为计算机。当然做的事情更简单一些。
字节码,就是说操作码是用一个字节来表示的。这就限制了操作码的个数不错过256个。当然class 文件中的一条指令可以由多个字节组成, 一条指令不光包括了操作码,还包括操作数。
当然字节码我们无法直接理解。jdk 中提供了工具(javap) 可以将字节码翻译成文字的形式,就像汇编是机器码的文字表现形式。

理解一段简单的字节码

  • 我们定义了一个java 文件
   //A.java
   public class A {
    public static void main ( String[] args ) {
        int a=0;
        int b =a + 1 ;
    }
}
  • 编译java 文件
   javac A.java   这样会生成A.class( 字节码文件) 
  • 显示字节码文件(A.class) 详情
   javap -c A.class
  • 下面对字节码的内容(上面命令的输出)进行一个简单的说明
Compiled from "A.java"
public class A {
  public A();  # 这里是构造方法,如果我们在程序里没有写构造方法, javac会为我们创建一个
    Code:
       0: aload_0     #将this 放到operand stack
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V ,将stack上的this 给 object 的<init>
       4: return

  public static void main(java.lang.String[]);   #这里是我们的程序入口main
    Code:
       0: iconst_0  # 将常量0  加载到操作数栈上
       1: istore_1  # 将栈顶操作数弹出回复到第一个本地变量, 也就是java 代码里边a 变量
       2: iload_1   # 把第一个变量 a 加载到栈顶
       3: iconst_1  # 把常数1 加载到栈顶
       4: iadd      # 执行add 操作, add 需要两个操作数,那么他会弹出两个栈顶的元素进行计算,并把计算结果放到栈顶
       5: istore_2  # 把栈顶元素恢复到第二个本地变量( 也就是b) 中
                    #  这里可以看到 实现b=a+1 使用了从2-5,共四条字节码指令
       6: return
}

这样对字节码有了大体的认识。

猜你喜欢

转载自blog.csdn.net/taozhen1987/article/details/80374277