(1)java虚拟机一些基本情况
java作为一门高级程序语言,语法非常复杂,抽象程度很高,因此,直接在硬件上运行这种复杂的程序并不现实,所以在运行java程序之前,我们需要对其进行一些转换。
进行转换的主流思路为,设计一个面向java语言特性的虚拟机,并通过编译器将java程序转换为该虚拟机所能识别的指令序列,也称java字节码,之所以叫这个名字,是因为java字节码的指令的操作码被固定为一个字节。
java虚拟机可以有硬件实现,但更为常见的是各个平台,例如windows、linux上提供的软件实现,这样一旦一个java程序被转为java字节码,就可以在各个平台上运行,这就是所说的“一次编写,到处运行”。
虚拟机除了带来跨平台运行的实现,同时也带来了一个托管环境,这个托管环境能帮我们处理一些代码中冗长而且容易出错的部分,其中最广为人知的就是自动内存管理与垃圾回收,这部分内容甚至催生了一些垃圾回收调优的业务,除此之外,托管环境还提供诸如数组越界、动态类型、安全权限等等的动态检测,是我们便于书写这些无关业务逻辑的代码。
(2)java虚拟机具体是怎么运行java字节码的
Java虚拟机在执行java代码时,首先需要将他编译而成的class文件加载入虚拟机中,加载后的java代码被保存在方法区中,实际运行时,虚拟机会运行方法区的代码。
在java虚拟机中,被分为线程共享的方法区、堆,以及线程不共享的java方法栈、本地方法栈、pc寄存器(存放各个线程执行位置)。
在调用过程中,每调用一个java方法,就会在当前线程的java方法栈中插入一个栈帧,用来存放局部变量以及字节码的操作数,这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。当退出当前执行的方法时,不管是正常返回还是异常返回,java虚拟机均会弹出当前线程的当前栈帧,并将其丢弃。
同时在硬件角度,java字节码是无法直接执行,因此java虚拟机需要将字节码翻译为机器码。
在HotSpot中,上述翻译过程有两种形式,第一种是解释执行,即逐条将字节码翻译为机器码,第二种是及时编译,一个方法中所有字节码全部编译成机器码才开始执行。
前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。HotSpot为了提高运行效率,采用了一种混合执行的策略,它会解释执行 Java 字节码,然后会将其中反复执行的热点代码,以方法为单位进行即时编译,翻译成机器码后直接运行在底层硬件之上。
(3)补充
java虚拟机将boolean类型当作int类型来看待
1 public classFoo {2 public static voidmain(String[] args ) {3 boolean flag = true;4 if(flag) {5 System.out.println("Hello, JAVA!");6 }7 if (flag == true) {8 System.out.println("Hello, JVM!");9 }10 }11 }
上述代码加载入java虚拟机后,会将flag看作int,所以第一个if判断是在判断flag是否等于0,第二个判断是在判断flag和true的值是否相等。