jvm本质上是运行在计算机上的程序,负责运行java字节码文件
对字节码文件中的指令,实时的解释成机器码,供计算机执行
自动为对象、方法等分配内存
自动垃圾回收机制,回收不再使用的对象
在java中每次执行都需要实时解释字节码文件成机器码,导致效率较低、速度变慢。这么做的原因是因为需要跨平台,不同操作系统的java虚拟机不同,解释编译的也不一样,不同的虚拟机会转成当前操作系统的字节码。
即时编译就是为了解决这个性能问题。JVM会识别热点代码(短时间多次调用), 会主动优化并且解释成机器码 ,将这个机器码保存在内存中。下次如果调用这段热点代码会直接从内存中取出调用。这样就省略了一次解释的步骤。这样在某些情况下性能就会提升很大
使用工具jclasslib工具查看class字节码
class字节文件的头文件的前四个字节是检验文件类型用的,class字节文件的头文件为CAFEBABE
public class HelloWorld {
public static void main(String[] args) {
int i = 0 ;
int j = i+1;
System.out.println(j);
}
}
对应的.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 #方法结束
public class HelloWorld {
public static void main(String[] args) {
int i = 0 ;
i = i++;
System.out.println(i);
}
}
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
public class HelloWorld {
public static void main(String[] args) {
int i = 0 ;
i = ++i;
System.out.println(i);
}
}
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