1 为什么要把Java源码编译成字节码,而非机器码?
由于不同的操作系统,相同程序编译后的机器码会不同,所以Java会使用JVM来屏蔽操作系统的差异,而在JVM上直接可以运行的就是Java编译后的字节码(.class);
2 Java是属于静态语言还是动态语言?动态语言的好处?
动态类型语言:指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。
静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型。
对于动态语言与静态语言的区分,套用一句流行的话就是:Static typing when possible, dynamic typing when needed。
综上所述,Java是属于静态语言,因为在编译阶段就要确定所有变量的数据类型。然而Java编译后并不是机器码,而是JVM解释执行的字节码。所以,其稍微有些动态语言的特性:解释执行。
3 JVM启动流程?
- 当执行java命令时,程序会去寻找合适的JRE的home位置;
- 在JRE/lib/cpu_arch(cpu的架构)/JVM.cfg下找到这个配置文件,确定JVM类型;
- 确定JVM类型后就可以基于LoadLibrary来加载JVM.dll文件,对启动参数进行解析,完成JVM的创建准备工作;
- 装载完JVM环境后就可以使用里面的函数,调用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获得JNIEnv结构的实例;
- JVM初始化结束之后,在启动通过findClass等操作加载Main入口类,调用main方法执行Java程序的后续操作;
4 为什么会存在JVM,其有哪些优势?
JVM屏蔽不同操作系统的差异,JVM经过长期发展已足够成熟和完善。一个完整的语言包括:前端、优化、后端、runtime、库。
5 JIT即时编译是什么及其作用?
Java程序最初是仅仅通过解释器解释执行的,即对字节码逐条解释执行,这种方式的执行速度相对会比较慢,尤其当某个方法或代码块运行的特别频繁时,这种方式的执行效率就显得很低。
于是后来在虚拟机中引入了JIT编译器(即时编译器),当虚拟机发现某个方法或代码块运行特别频繁时,就会把这些代码认定为“Hot Spot Code”(热点代码),为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各层次的优化,完成这项任务的正是JIT编译器。
6 JIT是如何检测热点代码的?
运行过程中会被即时编译器编译的“热点代码”有两类:
- 被多次调用的方法。
- 被多次调用的循环体
两种情况,编译器都是以整个方法作为编译对象,这种编译也是虚拟机中标准的编译方式。要知道一段代码或方法是不是热点代码,是不是需要触发即时编译,需要进行Hot Spot Detection(热点探测)。目前主要的热点判定方式有以下两种:
基于采样的热点探测:采用这种方法的虚拟机会周期性地检查各个线程的栈顶,如果发现某些方法经常出现在栈顶,那这段方法代码就是“热点代码”。这种探测方法的好处是实现简单高效,还可以很容易地获取方法调用关系,缺点是很难精确地确认一个方法的热度,容易因为受到线程阻塞或别的外界因素的影响而扰乱热点探测。
基于计数器的热点探测:采用这种方法的虚拟机会为每个方法,甚至是代码块建立计数器,统计方法的执行次数,如果执行次数超过一定的阀值,就认为它是“热点方法”。这种统计方法实现复杂一些,需要为每个方法建立并维护计数器,而且不能直接获取到方法的调用关系,但是它的统计结果相对更加精确严谨。
7 JVM主要分为哪主要三部分结构?
JVM主要分为类加载器、执行引擎、运行时数据区域;
8 JVM运行时数据区域有哪些组成?
JVM运行时数据区域:方法区、Java堆、Java栈、本地方法栈;
9 JVM的内存区域,哪些是线程共享的、线程私有的?
线性共享:方法区、Java堆;
线程私有:Java栈、本地方法栈;
10 为什么有些JVM会选择用解释器+JIT编译器的混合执行引擎?
现在主流的商用虚拟机(如Sun HotSpot、IBM J9)中几乎都同时包含解释器和编译器(三大商用虚拟机之一的JRockit是个例外,它内部没有解释器,因此会有启动相应时间长之类的缺点,但它主要是面向服务端的应用,这类应用一般不会重点关注启动时间)。二者各有优势:当程序需要迅速启动和执行时,解释器可以首先发挥作用,省去编译的时间,立即执行;当程序运行后,随着时间的推移,编译器逐渐会返回作用,把越来越多的代码编译成本地代码后,可以获取更高的执行效率。解释执行可以节约内存,而编译执行可以提升效率。
11 为何HotSpot会使用两种不同的Client/Server模式即时编译?
HotSpot虚拟机中内置了 两个JIT编译器:Client Complier和Server Complier,分别用在客户端和服务端,目前主流的HotSpot虚拟机中默认是采用解释器与其中一个编译器直接配合的方式工作。