Java 虚拟机(JVM)是运⾏ Java 字节码的虚拟机。JVM 有针对不同系统的特定实现 (Windows,Linux,macOS),⽬的是使⽤相同的字节码,它们都会给出相同的结果。
在 Java 中,JVM 可以理解的代码就叫做(即扩展名为 .class 的⽂件),它不⾯ 向任何特定的处理器,只⾯向虚拟机。Java 语⾔通过字节码的⽅式,在⼀定程度上解决了 传统解释型语⾔执⾏效率低的问题,同时⼜保留了解释型语⾔可移植的特点。所以 Java 程 序运⾏时⽐⾼效,⽽且,由于字节码并不针对⼀种特定的机器,因此,Java 程序⽆须重 新编译便可在多种不同操作系统的计算机上运⾏。
Java 程序从源代码到运⾏⼀般有下⾯ 3 步:
我们需要格外注意的是 .class->机器码 这⼀步。在这⼀步 JVM 类加载器⾸先加载字节码⽂件, 然后通过解释器逐⾏解释执⾏,这种⽅式的执⾏速度会相对⽐较慢。⽽且,有些⽅法和代码块是 经常需要被调⽤的(也就是所谓的热点代码),所以后⾯引进了 JIT 编译器,⽽ JIT 属于运⾏时编 译。当 JIT 编译器完成第⼀次编译后,其会将字节码对应的机器码保存下来,下次可以直接使 ⽤。⽽我们知道,机器码的运⾏效率肯定是⾼于 Java 解释器的。这也解释了我们为什么经常会 说 Java 是编译与解释共存的语⾔。
HotSpot 采⽤了惰性评估(Lazy Evaluation)的做法,根据⼆⼋定律,消耗⼤部分系统资源的 只有那⼀⼩部分的代码(热点代码),⽽这也就是 JIT 所需要编译的部分。JVM 会根据代 码每次被执⾏的情况收集信息并相应地做出⼀些优化,因此执⾏的次数越多,它的速度就越 快。JDK 9 引⼊了⼀种新的编译模式 AOT(Ahead of Time Compilation),它是直接将字节码 编译成机器码,这样就避免了 JIT 预热等各⽅⾯的开销。JDK ⽀持分层编译和 AOT 协作使 ⽤。但是 ,AOT 编译器的编译质量是肯定⽐不上 JIT 编译器的。
总结:Java 虚拟机(JVM)是运⾏ Java 字节码的虚拟机。JVM 有针对不同系统的特定实现 (Windows,Linux,macOS),⽬的是使⽤相同的字节码,它们都会给出相同的结果。字节码 和不同系统的 JVM 实现是 Java 语⾔“⼀次编译,随处可以运⾏”的关键所在。