JAVA本身是一种面向对象的语言,最显著的特性有两个方面:一次编译,到处运行和垃圾回收

先说说我对一次编译,到处运行的理解

       “一次编译,到处运行”说的是java语言跨平台的特性。

         JAVA是一种编译型-解释型语言,当执行java文件时,编译器首先会将.java类型的源文件编译成.class类型的字节码文件。之后jvm虚拟机再运行编译好的字节码文件时,将字节码文件解释成具体平台上的机器指令。java的跨平台特性与jvm虚拟机的存在密不可分,jvm虚拟机可以使java语言在不同的环境中运行。比如Windows平台和Linux平台都有相应的JDK,安装好jdk后也就有了JAVA语言的运行环境。其实JAVA语言本身与其他编程语言没有特别大的差异,并不是说java语言可以跨平台,而是在不同的平台安装不同版本的jdk,都能有让java语言有可以运行的环境。

       当然,跨平台的语言不止java一种。例如C++,它是一种编译型语言,其源代码是直接经过编译器编译成“操作系统”可以执行的“机器码”,这个功能的实现依赖于不同平台上使用的不同的编译器。但目前来看,java的跨平台更成熟。编程语言的处理需要编译器和解释器。jvm虚拟机和用cmd打开的dos类似,相当于一个供程序运行的平台。(小知识:js属于解释型语言,直接执行,没有编译过程。上面的java的编译型都需要整体编译,再一次执行。而解释程序是边解释,边执行)

      java程序从源代码到运行分为三个阶段:编码(生成字节码文件)--编译(jvm将字节码转化成机器码)--运行--调试。然而通过jvm类加载器加载字节码文件,然后通过解释器逐行解释执行,这种方法执行速度相对会比较慢。有些方法和代码块是高频率调用,也就是所谓的热点代码,根据二八定律,消耗大部分系统资源的只有那一小部分代码,因此后来引入了JIT技术,JVM根据代码每次被执行的情况收集信息,提前将这类字节码文件直接编译成本地机器码。这样类似于缓存技术,运行时遇到这类代码直接可以执行,无须编译再解释后执行。(小知识:JIT为方法级,它会缓存编译过的字节码在CodeCache中,而不需要重复解释。那么jit是如何找到热点代码的呢,这边就要介绍下hotpost,hospost热点探测使用的方法是调用计数器和回边计数器,虚拟机为每个代码块,每个方法,建立计数器,统计执行次数,超过一定阀值,就视为热点代码,这种实现较为复杂,但结果更为严谨)

JDK 9 引入了一种新的编译模式:AOT(Ahead of Time Compliaction),他是将字节码文件直接编译成机器码,这样就避免了JIT预热等各方面的开销。JDK支持分层编译和AOT编译协作使用。