java语言的“编译期”是一段不确定的过程。由于它可能指的是前端编译器把java文件转变成class字节码文件的过程,也可能指的是虚拟机后端执行期间编译器(JIT)把字节码转变成机器码的过程。
以下讨论的编译期优化指的是javac编译器将java文件转化为字节码的过程,而执行期间优化指的是JIT编译器所做的优化。
编译期优化
虚拟机设计团队把对性能的优化集中到了后端的即时编译器(JIT)中,这样能够让那些不是由javac编译器产生的class文件也相同能享受到编译器优化所带来的优点。

可是javac做了很多针对编码过程的优化措施来改善程序猿的编码风格和提高编码效率。很多新生的java语法特性,都是靠编译器的“语法糖”来实现,而不是依赖虚拟机的底层改进来支持。

所以说,java中即时编译器在执行期间的优化过程对于程序的执行来说更重要,而前端编译器在编译期的优化过程对于程序编码来说关系更加密切。
javac编译器的编译过程大致可分为三个步骤:
1.解析与填充符号表过程;
2.插入式注解处理器的注解处理过程;
3.语义分析与字节码生成过程。
以下分别来介绍。

解析与填充符号表;
解析步骤包括了词法分析和语法分析两个过程,首先词法分析是将源码的字符流转变成为标记集合(token)。然后语法分析是根据token序列来构造抽象语法树(一种用来描写叙述程序代码语法结构的树状表示方式)。完毕词法分析和语法分析之后,下一步是填充符号表,符号表是由一组符号地址和符号信息构成的表格,符号表中所登记的信息在编译的不同阶段都要用到(比方语义分析中符号表所登记的内容将用于语义检查和产生中间代码,目标代码生成阶段当对符号名进行地址分配时,符号表是地址分配的根据)。
插入式注解处理器的注解处理过程:
插入式注解处理器能够看做是一组编译器的插件。在这些插件里面。能够读取、改动、加入抽象语法树中的随意元素。假设这些插件在处理注解期间对语法树进行了改动,那么编译器将回到解析及填充符号表的过程又一次处理,直到全部的插入式注解处理器都没有再对语法树进行改动为止。
语义分析与字节码生成过程:
语法分析之后,编译器获得了程序代码的抽象语法树表示,语法树可以表示结构正确的源程序的抽象,可是无法保证源程序是否符合逻辑,而语义分析主要是对结构上正确的源程序进行上下文有关性质的检查。

1.标注检查
    标注检查步骤检查的内容包含诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否可以匹配。等等。另一个重要的动作称为常量折叠也在此阶段完毕。
2.数据及控制流分析
     数据及控制流分析是对程序上下文逻辑更进一步的验证,它能够检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否有返回值、是否全部的受查异常都被正确处理了等问题。
3.解语法糖
       语法糖是指在计算机语言中加入某种语法,这样的语法对语言的功能并没有影响,可是更方便程序猿使用。

java中的泛型。变长參数,自己主动拆箱与装箱,条件编译等就属于语法糖。它们在编译阶段就被还原成简单的语法结构(比方List<String>和List<Integer>在执行期间事实上是同一个类)。

4.字节码生成
此过程是javac编译过程的最后一个阶段,字节码生成阶段将之前各个步骤所生成的信息转化成字节码写到磁盘中,另外还进行少量的代码加入和转换工作。


执行期优化
在部分商用虚拟机中。java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块执行特别频繁,就会把这些代码认定为“热点代码”,为了提高热点代码的执行效率,在执行时,虚拟机就会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完毕这个任务的编译器称为即使编译器或JIT编译器。
即时编译器并非虚拟机必须的部分,可是即时编译器编译性能的好坏、代码优化程度的高低确是衡量一款商用虚拟机优秀与否的最关键的指标之中的一个。
众多主流的虚拟机都同一时候包括解释器和JIT编译器,解释器与JIT编译器各有优势:当程序须要迅速启动和运行时,解释器能够首先发挥作用,省去编译的时间,马上运行。当程序运行后,随着事件的推移。JIT编译器逐渐发挥作用。把越来越多的代码编译成本地代码之后。能够获取更高的运行效率。


会被即时编译器编译的热点代码有两类:
1.被多次调用的方法体。
2.被多次调用的循环体。

即时编译器会以整个方法作为编译对象。将其编译成机器码。

这样的编译方式由于编译发生在方法运行过程之中,因此被称作栈上替换(OSR)。

推断一段代码是否是热点代码的方式(热点探測)有两种:
1.基于採样的热点探測:
此方法会周期性检查各个线程的栈顶。假设发现某个或某些方法常常出如今栈顶。那么这种方法就是热点方法。此方法的缺点是非常难精确地确认一个方法的热度。easy受到诸如线程堵塞等因素影响。
2.基于计数器的热点探測:
此方法会为每一个方法甚至是代码块建立计数器。统计方法的运行次数,假设运行次数超过一个阀值就觉得它是热点方法。
注:默认设置下,运行引擎并不会同步等待编译请求完毕。而是继续进入解释器依照解释方式运行字节码,直到提交的请求被编译器编译完毕。当编译工作完毕之后,这种方法的调用入口地址就会被系统自己主动改写成新的地址,下一次调用该方法时就会使用已编译的版本号。也就是说,在编译器还未完毕之前,运行引擎仍依照解释方式继续运行。而编译动作则在后台的编译线程中进行。
优化技术:
一般来说即时编译器所产生的本地代码会比javac产生的字节码更优秀。即时编译器採用了一系列的技术来优化代码。比方公共子表达式消除,数组范围内检查消除。方法内联,逃逸分析等。

java编译期优化与执行期优化技术浅析的更多相关文章

  1. Java编译期注解处理器详细使用方法

    目录 Java编译期注解处理器 启用注解处理器 遍历语法树 语法树中的源节点 语法树节点的操作 给类增加注解 给类增加import语句 构建一个内部类 使用方法 chainDots方法 总结 Java ...

  2. java编译期优化

    java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程: 1.前端编译:把.java文件转变为.class文件 2.后端编译:把字节码转变为机器码 3.静态提前编译:直接把*.ja ...

  3. java 编译期常量

    今天在看书的时候遇到了一个不是很懂的名词,是在think in java 这本书的第七章讲final关键字时讲到的.然后自己在网上查了一下知道了一些. 编译器常量就是:它的值在编译期就可以确定的常量. ...

  4. Java编译期与运行期

    编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本 ...

  5. 深入了解JVM虚拟机8:Java的编译期优化与运行期优化

    java编译期优化 java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程:1.前端编译:把.java文件转变为.class文件2.后端编译:把字节码转变为机器码3.静态提前编译: ...

  6. JVM笔记——编译期的优化

    一.编译过程 解析和填充符号表的过程 插入注解处理器的注解处理过程 语义分析与字节码生成过程 二.解析和填充符号表 解析包含两个过程:词法分析和语法分析 (一)词法分析 将源代码的字符流转变成标记(T ...

  7. 深入理解JVM - 早期(编译期)优化

    Java“编译期”是一段“不确定”的操作过程:可能是指一个前端编译器(编译器的前端)把*.java文件转变为*.class文件的过程:可能是指虚拟机的后端运行期编译器(JIT编译器,Just In T ...

  8. 数值类型中JDk的编译期检查和编译期优化

    byte b1 = 5;//编译期检查,判断是否在byte范围内 byte b2 = 5+4;//编译期优化,相当于b2=9 byte b3 = 127;//编译通过,在byte范围内 byte b4 ...

  9. 《深入理解Java虚拟机》-----第10章 程序编译与代码优化-早期(编译期)优化

    概述 Java语言的“编译期”其实是一段“不确定”的操作过程,因为它可能是指一个前端编译器(其实叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指虚拟机的后端运 ...

随机推荐

  1. system.getProperties()

    Properties props=System.getProperties(); //系统属性     System.out.println("Java的运行环境版本:"+prop ...

  2. JS判断终端(Android IOS)

    function getMobileOperatingSystem() { var userAgent = navigator.userAgent || navigator.vendor || win ...

  3. IoC模式(控制反转)(转)

    转自:http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html,写的很好,用C#代码解释控制反转,然后更进一步,提到依赖注入是控制反转的 ...

  4. Fedora上配置一个安全FTP

    现在流行的FTP服务器,比较著名的有WU-FTP(Washington University FTP)和VSFTP(Very Secure FTP 非常安全的FTP)以及Proftp,pureftp等 ...

  5. angular post发送请求和GET发送请求,服务器端接收不到信息的问题

    参数可能因为编码原因,服务器端无法接收到传递的值, 这时需要用到补丁来解决这个问题 1,下载一个http.patch.js文件,放入YII框架中的js/ng文件架内 2angularjs 创建模型部分 ...

  6. python json string和dict的转化

    __author__ = 'SRC_TJ_XiaoqingZhang' import json data1 = {'b': 789, 'c': 456, 'a': 123} encode_json = ...

  7. python模块之re正则表达式

    41.python的正则表达式      1. python中re模块提供了正则表达式相关操作 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字      \W大写代表非\w ...

  8. window bzr launchpad 安装配置

    1: https://launchpad.net/bzr/2.6/2.6b1/+download/bzr-2.6b1-1-setup.exe 使用Standalone版本  , 安装时选择plugin ...

  9. sdk manager更新失败,显示Download interrupted: read timed out,应该如何解决?

    今天开始第一天学习Android,就遇到一个大问题.sdk manager无法自动更新,总在提示超时!!! 经过网上查询发现问题原因是. 在利用android sdk manager更新时失败,具体情 ...

  10. ASP.NET关于引用bootstrap.css导致Gridview Header无法居中

    HorizontalAlign="Center"  属性因不知名原因被覆盖掉. 可以使用<HeaderStyle  CssClass="text-center&qu ...