语义分析
语法树能表示一个结构正确的源程序的抽象,但无法保证源程序是符合逻辑的 。而语义分析的主要任务是读结构上正确的源程序进行上下文有关性质的审查 。语义分析过程分为标注检查和数据及控制流分析两个步骤:
标注检查步骤检查的内容包括诸如变量使用前是否已被声明、变量和赋值之间的数据类型是否匹配等 。
数据及控制流分析是对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等问题 。
字节码生成
字节码生成是Javac编译过程的最后一个阶段 。字节码生成阶段不仅仅是把前面各个步骤所生成的信息转化成字节码写到磁盘中,编译器还进行了少量的代码添加和转换工作 。实例构造器init()方法和类构造器clinit()方法就是在这个阶段添加到语法树之中的(这里的实例构造器并不是指默认的构造函数 , 而是指我们自己重载的构造函数,如果用户代码中没有提供任何构造函数,那编译器会自动添加一个没有参数、访问权限与当前类一致的默认构造函数 , 这个工作在填充符号表阶段就已经完成了) 。
JIT编译
Java程序最初是仅仅通过解释器解释执行的 , 即对字节码逐条解释执行,这种方式的执行速度相对会比较慢,尤其当某个方法或代码块运行的特别频繁时,这种方式的执行效率就显得很低 。于是后来在虚拟机中引入了JIT编译器(即时编译器),当虚拟机发现某个方法或代码块运行特别频繁时,就会把这些代码认定为“Hot Spot Code”(热点代码) , 为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码 , 并进行各层次的优化 , 完成这项任务的正是JIT编译器 。
现在主流的商用虚拟机(如Sun HotSpot、IBM J9)中几乎都同时包含解释器和编译器(三大商用虚拟机之一的JRockit是个例外,它内部没有解释器,因此会有启动相应时间长之类的缺点,但它主要是面向服务端的应用,这类应用一般不会重点关注启动时间) 。二者各有优势:当程序需要迅速启动和执行时 , 解释器可以首先发挥作用,省去编译的时间,立即执行;当程序运行后,随着时间的推移,编译器逐渐会返回作用,把越来越多的代码编译成本地代码后,可以获取更高的执行效率 。解释执行可以节约内存,而编译执行可以提升效率 。
HotSpot虚拟机中内置了两个JIT编译器:Client Complier和Server Complier,分别用在客户端和服务端,目前主流的HotSpot虚拟机中默认是采用解释器与其中一个编译器直接配合的方式工作 。
运行过程中会被即时编译器编译的“热点代码”有两类:
被多次调用的方法 。
被多次调用的循环体 。
两种情况,编译器都是以整个方法作为编译对象,这种编译也是虚拟机中标准的编译方式 。要知道一段代码或方法是不是热点代码,是不是需要触发即时编译,需要进行Hot Spot Detection(热点探测) 。目前主要的热点 判定方式有以下两种:
基于采样的热点探测:采用这种方法的虚拟机会周期性地检查各个线程的栈顶,如果发现某些方法经常出现在栈顶,那这段方法代码就是“热点代码” 。这种探测方法的好处是实现简单高效,还可以很容易地获取方法调用关系,缺点是很难精确地确认一个方法的热度 , 容易因为受到线程阻塞或别的外界因素的影响而扰乱热点探测 。
基于计数器的热点探测:采用这种方法的虚拟机会为每个方法,甚至是代码块建立计数器,统计方法的执行次数,如果执行次数超过一定的阀值,就认为它是“热点方法” 。这种统计方法实现复杂一些,需要为每个方法建立并维护计数器,而且不能直接获取到方法的调用关系,但是它的统计结果相对更加精确严谨 。
推荐阅读
- 姓氏头像直播素材,姓氏头像生成器软件更新下载
- 电商如何博取同情赚钱,电商怎么搞起来
- 如何去电脑推广软件给别人,电脑怎么推广
- 百度超级链小程序怎么预约,百度超级链为什么停止了更新
- java代码乘法口诀 java编程乘法口诀表
- c语言程序设计所学内容及收获,c语言程序设计总结与体会
- 手机上的虚拟机在哪,手机上的虚拟机在哪下载
- 鹏鹏为什么没有直播了,鹏鹏现在在哪里直播啊
- 关于vb.netsms通知的信息