一、谈谈对Java平台的理解:
Java是一种面向对象的语言,最显著的特性有两个方面,一是“write once, run anywhere ”,能够非常容易地获得跨平台能力;另外就是垃圾收集(GC),Java通过垃圾收集器回收分配的内存,大部分情况下,程序员不需要自己对内存的分配和回收进行管理。
我们日常接触到的JRE是Java运行环境,包含JVM和Java类库以及一些模块等,JDK可以看作是JRE的一个超集,提供了更多工具,如编译器、各种诊断工具等。
对Java平台的理解可以从很多方面总结、思考,如Java语言特性,包括泛型、lambda等语言特性;基础类库,包括集合、I/O,NIO,网络、并发、安全等基础类库等等。
或者从JVM角度谈,如Java类加载机制、常用版本jdk内嵌的类加载器,如bootstrap、application和extension 类加载器;类加载大致过程:加载、验证、链接、初始化;自定义ClassLoader等;还有垃圾收集的基本原理,最常见的垃圾收集器,如SerialGC、ParallelGC、CMS、G1等,对于适用于怎样的工作负载等
还有jdk包含哪些工具或者Java领域内其他工具等,如编译器、运行时环境、安全工具。诊断和监控工具,这些工具是日常工作效率的保证。
二、Java是解释执行的吗?
对于编写好的Java源代码,首先通过Javac编译成字节码(bytecode),然后在运行时,通过Java虚拟机(JVM)内嵌的解释器将字节码转换成最终的机器码。但是常见的虚拟机如Hotspot JVM,提供了JIT(Just-in-time)编译器,即使通常所说的动态编译器,JIT能够在运行时将热点代码(高频使用)编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行。
三、对解释执行与编译执行的理解:
Java分成编译期和运行时,这里的编译和C/C++有着不同的意义,Javac的编译,编译Java源码生成.class文件,即字节码文件,字节码不是可以直接执行的机器码。Java通过字节码和JVM这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现”一次编译,到处执行“的基础。
在运行时,JVM会通过类加载器classLoader加载字节码,解释或者编译执行,在主流Java版本中如jdk8,实际是解释和编译混合的一种模式,即混合模式(-Xmixed)。通常运行时在server模式的JVM,会进行上万次调用以收集足够的信息进行高效的编译,client模式这个门限是1500次,Oracle HotspotJVM内置了两个不同的JIT compiler,C1对应client模式,适用于对于启动速度敏感的应用,比如普遍的Java桌面应用;C2对应server模式,它的优化是为长时间运行服务器端应用设计的。默认是采用所谓的分层编译(TieredCompilation)。
Java虚拟机启动时,可以指定不同的参数对运行模式进行选择。如,指定-Xint,则告诉JVM只进行解释执行,不对代码进行编译,这种模式抛弃了JIT可能带来的性能优势,解释器(interpreter)是逐条读入,逐条解释运行的。
另一参数是-Xcomp,这是告诉JVM关闭解释器。不要进行解释执行,或者叫做最大优化级别。-Xcomp会导致JVM启动变得非常慢,同时有些JIT编译器优化的方式,比如分支预测,如果不进行profiling,往往并不能进行有效优化
此外,在jdk9引入了实验性的AOT特性,AOT(Ahead-of-Time Compilation),是一种新的编译方式,可以直接将字节码编译成机器代码,这样可以避免JIT预热等各方面的开销,同时jdk9也增加了新的jaotc工具,利用以下命令可以把某个类或者某个模块编程成AOT库:
jaotc --output libHelloWorld.so HelloWord.class
jaotc --output libjava.base.so --module java.base
然后在启动时直接指定:
java -XX:AOTLibrary=./libHelloWorld.so, ./libjava.base.so HelloWorld
jdk支持分成编译和AOT协作使用,AOT也不仅仅是只有这一种方式,业界有第三方工具,如GCJ 、Excelsior JET等提供相关功能。
总结:JVM作为一个强大的平台,不仅仅只有Java语言可以运行在JVM上,本质上合规的字节码都可以运行,Java语言自身提供了便利。
声明:本文仅为个人的学习总结,学习自:极客时间《Java核心36讲》
网友评论