【Java】JVM字节码分析

一、功能

1、工作原理

2、解释和运行

jvm本质上是运行在计算机上的程序,负责运行java字节码文件

对字节码文件中的指令,实时的解释成机器码,供计算机执行

3、内存管理

自动为对象、方法等分配内存

自动垃圾回收机制,回收不再使用的对象

4、 即时编译

在java中每次执行都需要实时解释字节码文件成机器码,导致效率较低、速度变慢。这么做的原因是因为需要跨平台,不同操作系统的java虚拟机不同,解释编译的也不一样,不同的虚拟机会转成当前操作系统的字节码。

即时编译就是为了解决这个性能问题。JVM会识别热点代码(短时间多次调用), 会主动优化并且解释成机器码 ,将这个机器码保存在内存中。下次如果调用这段热点代码会直接从内存中取出调用。这样就省略了一次解释的步骤。这样在某些情况下性能就会提升很大

二、解释字节码

使用工具jclasslib工具查看class字节码

class字节文件的头文件的前四个字节是检验文件类型用的,class字节文件的头文件为CAFEBABE

1、分析class文件

java 复制代码
public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        int j = i+1;
        System.out.println(j);
    }
}

对应的.class字节文件为

class 复制代码
 0 iconst_0    #将常量0放入操作数栈中
 1 istore_1    #将操作数栈顶的数值存储到局部变量表1的位置
 2 iload_1     #将局部变量表1中的数复制到栈上
 3 iconst_1    #将常量1放入操作数栈中栈中
 4 iadd        #将栈中最上面两个值进行相加,存储到栈顶
 5 istore_2    #从栈中取出操作数放入局部变量表中2号位置
13 return      #方法结束

2、分析i++

java 复制代码
public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        i = i++; 
        System.out.println(i);
    }
}
class 复制代码
 0 iconst_0       #将常量0放入操作数栈
 1 istore_1       #将栈顶元素取出存储到局部变量表1的位置
 2 iload_1        #将局部变量表1位置的操作数复制到操作栈
 3 iinc 1 by 1    #将布局变量表1的位置的值加1
 6 istore_1       #将栈顶元素取出存储到局部变量表1的位置
10 iload_1        #将布局变量表1位置的操作数复制到操作数栈
14 return

结果输出为0

3、分析++i

java 复制代码
public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        i = ++i; 
        System.out.println(i);
    }
}
class 复制代码
 0 iconst_0       #将常量0放入操作数栈
 1 istore_1       #将栈顶元素取出存储到局部变量表1的位置
 2 iinc 1 by 1    #将布局变量表1的位置的值加1
 5 iload_1        #将布局变量表1位置的操作数复制到操作数栈
 6 istore_1       #将栈顶元素取出存储到局部变量表1的位置
10 iload_1        #将布局变量表1位置的操作数复制到操作数栈
14 return

输出结果为1