七 晚期(运行期)优化
1 即时编译器(JIT编译器)
    ---当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“热点代码”,包括被多次调用的方法和被多次执行的循环体。
    ---为了提高热点代码的执行效率,在运行时,虚拟机就会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(JIT编译器)。
    ---即时编译器不是虚拟机必需的部分,虚拟机规范对其没有做任何规定,与具体的虚拟机实现有关。
 
2 解释器与编译器
    ---许多主流的商用虚拟机如HotSpot,都同时包含解释器和编译器。
    ---解释器和编译器两者各有优势:
        · 当程序需要迅速启动和执行的时候。解释器可以首先发挥作用,省去编译的时间,立即执行;
        · 在程序运行后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码后,可以获取更高的执行效率;
        · 当程序运行环境中内存资源限制较大,可以使用解释执行节约内存,反之,可以使用编译执行提升效率;
        · 解释器还可以作为编译器激进优化时的一个“逃生门”。
    ---HotSpot虚拟机中内置了两个即时编译器:Client Compiler(C1编译器)、Server Compiler(C2编译器)。默认采用解释器与其中一个编译器直接配合的方式工作,程序使用哪个编译器取决于虚拟机运行的模式。
    ---分层编译策略:
        · 第0层,程序解释执行,解释器不开启性能监控功能,可触发第1层编译;
        · 第1层,也称为C1编译,将字节码编译为本地代码,进行简单、可靠的优化,如有必要将加入性能监控的逻辑;
        · 第2层,也称为C2编译。将字节码编译为本地代码,会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。
 
3 编译对象和触发条件
    ---JIT编译方式:方法被多次调用触发的编译,编译器以整个方法作为编译对象。
    ---栈上替换(OSR编译):循环体被多次执行触发的编译,编译器同样以整个方法作为编译对象。
    ---热点探测:判断一段代码是不是热点代码,是不是需要触发即时编译。目前主要的判定方式有两种:
        · 基于采样的热点探测:虚拟机会周期性地检查各个线程的栈顶,如果发现某个方法经常出现在栈顶,那这个方法就是“热点方法”。
            ---优点:实现简单、高效,可以很容易地获取方法调用关系。
            ---缺点:很难精确地确认一个方法的热度,容易因为受到线程阻塞或别的外界因素的影响而扰乱热点探测。
        · 基于计数器的热点探测:虚拟机会为每个方法(甚至是代码块)建立计数器,统计方法的执行次数,如果执行次数超过一定的阈值就认为它是“热点方法”。
            ---优点:统计结果更加精确和严谨。
            ---缺点:实现比较复杂,不能直接获取到方法调用关系。
    ---在HotSpot虚拟机中使用的是基于计数器的热点探测,它为每个方法准备了两类计数器:方法调用计数器和回边计数器。
    ---方法调用计数器:统计方法被调用的次数,在Client VM下,其触发的即时编译过程如下:
                        
    ---方法调用计数器热度的衰减:当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少到一半。一般是在虚拟机进行垃圾收集时顺便进行的。也可以设置为不进行热度衰减。
    ---回边计数器:统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”。
    ---回边计数器阈值计算公式:
        · 虚拟机运行在Client模式下,计算公式为:方法调用计数器阈值*OSR比率/100;
        · 虚拟机运行在Server模式下,计算公式为:方法调用计数器阈值*(OSR比率-解释器监控比率)/100。
    ---在Client VM下,回边计数器触发的即时编译过程如下:
                            
    ---回边计数器没有热度衰减的过程。当计数器溢出时,它还会把方法计数器的值也调整到溢出状态,这样下次再进入该方法的时候就会执行标准编译过程(JIT编译)。
 
4 编译过程
    ---Server Compiler和Client Compiler两个编译器的编译过程是不一样的。
    ---Client Compiler主要的关注点在于局部性的优化,而放弃了许多耗时较长的全局优化手段,过程如下:
        · 一个平台独立的前端将字·节码构造成一种高级中间代码表示(HIR),在此之前编译器会在字节码上完成一部分基础优化,如方法内联、常量传播等;
        · 一个平台相关的后端从HIR中产生低级中间代码表示(LIR),在此之前编译器会在HIR上完成另外一些优化,如空值检查消除、范围检查消除等;
        · 在平台相关的后端使用线性扫描算法在LIR上分配寄存器,并在LIR上做窥孔优化,然后产生机器代码。
            
 
5 编译优化技术
    ---编译方式执行本地代码比解释方式更快的原因:
        · 虚拟机解释执行字节码时需要额外的消耗时间;
        · 虚拟机对代码的优化措施几乎都集中在即时编译器中。
    (1)方法内联
            ---主要目的是:
                · 去除方法调用的成本,如建立栈帧等;
                · 为其他优化建立良好的基础,方法内联膨胀之后可以便于在更大范围上采取后续的优化手段,从而获取更好的优化效果。
            ---Java虚拟机的内联过程:
                · 编译器在进行方法内联时,如果是非虚方法,那么可以直接进行内联。    
                · 如果是虚方法,则会向CHA查询此方法在当前程序下是否有多个目标版本可供选择,若查询结果只有一个版本,那也可以进行内联,但是这种内联属于激进优化,需要预留一个“逃生门”,称为守护内联。如果在程序的后续执行过程中,虚拟机一直没有加载到会令这个方法的接收者的继承关系发生变化的类,那这个内联优化的代码就可以一直使用下去。但如果加载了导致继承关系发生变化的新类,那就需要抛弃已经编译的代码,退回到解释状态执行,或者重新进行编译。
                · 如果CHA查询出来的结果是有多个版本的目标方法可供选择,则编译器会使用内联缓存来完成方法内联。
            ---注1:类型继承关系分析(CHA)技术:用于确定在目前已加载的类中,某个接口是否有多于一种的实现,某个类是否存在子类、子类是否为抽象类等信息。
            ---注2:内联缓存工作原理:在未发生方法调用之前,内联缓存状态为空,当第一次调用发生后,缓存记录下来方法接收者的版本信息,并且每次进行方法调用时都比较接收者版本,如果以后进来的每次调用的方法接收者版本都是一样的,那这个内联还可以一直用下去。如果发生了方法接收者版本不一致的情况,就说明程序真正使用了虚方法的多态特性,这时会取消内联,查找虚方法表进行方法分派。
 
    (2)公共子表达式消除
            ---含义是:如果一个表达式E已经计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E的这次出现就成为了公共子表达式。对于这种表达式,没有必要花时间再对它进行计算,只需要直接使用前面计算过的表达式结果代替E就可以了。
            ---语言无关的经典优化技术之一。
    (3)数组边界检查消除
            ---语言相关的经典优化技术之一。
            ---把运行期检查提到编译期完成。
    (4)逃逸分析
            ---逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,称为方法逃逸;甚至还有可能被外部线程访问到,称为线程逃逸。
            ---如果一个对象不会逃逸到方法或者线程之外,则可能为该变量进行如下优化:
                · 栈上分配:如果一个对象不会逃逸出方法之外,那么可以让这个对象在栈上分配内存。
                · 同步消除:如果一个对象不会逃逸出线程之外,那么可以将对这个对象的同步措施消除掉。
                · 标量替换:如果逃逸分析证明一个对象不会被外部访问,并且这个对象可以被拆散的话,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。
            ---注1:标量:一个数据已经无法再分解成更小的数据来表示,如Java虚拟机中的原始数据类型(int、long等数值类型及reference类型等)。
            ---注2:聚合量:一个数据可以继续分解,如Java中的对象。

深入理解Java虚拟机读书笔记7----晚期(运行期)优化的更多相关文章

  1. 深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域

    深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理 ...

  2. 【Todo】深入理解Java虚拟机 读书笔记

    有一个在线系列地址 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> http://book.2cto.com/201306/25426.html 已经下载了这本书(60多M ...

  3. 深入理解Java虚拟机读书笔记5----虚拟机字节码执行引擎

    五 虚拟机字节码执行引擎   1 运行时栈帧结构     ---栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,是虚拟机运行时数据区中的虚拟机栈的栈元素.     ---栈帧中存储了方法的局部变 ...

  4. 深入理解Java虚拟机读书笔记8----Java内存模型与线程

    八 Java内存模型与线程   1 Java内存模型     ---主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节.     ---此处的变量和J ...

  5. 深入理解Java虚拟机读书笔记6----早期(编译期)优化

    六 早期(编译期)优化   1 “编译期”的含义     · 可能是指一个前端编译器把*.java文件转变成*.class文件的过程,前端编译器如:Sun的Javac.Eclipse JDT中的增量式 ...

  6. 深入理解Java虚拟机读书笔记4----虚拟机类加载机制

    四 虚拟机类加载机制 1 类加载机制     ---概念:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型.     -- ...

  7. 深入理解Java虚拟机读书笔记3----类文件结构

    三 类文件结构 1 Java虚拟机的两种中立特性     · 平台无关性     · 语言无关性     实现平台无关性和语言无关性的基础是虚拟机和字节码存储格式(Class文件).   2 Clas ...

  8. 深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象

    一 Java内存区域与HotSpot虚拟机对象 1 Java技术体系.JDK.JRE?     Java技术体系包括:         · Java程序设计语言:         · 各种硬件平台上的 ...

  9. 深入理解java虚拟机读书笔记--java内存区域和管理

    第二章:Java内存区域和内存溢出异常 2.2运行时数据区域 运行时数据区分为方法区,堆,虚拟机栈,本地方法栈,程序计数器 方法区和堆是线程共享的区域 虚拟机栈,本地方法栈,程序计数器是数据隔离的数据 ...

随机推荐

  1. java删除文件支持通配符

    原文:https://blog.csdn.net/wdzayyt/article/details/7209530 感谢原作者 package com.covics.zfh; import java.i ...

  2. Java修饰符final总结

    final 的意思是最终的,不可改变的. final可以用来修饰 a.类. b.方法(包括类方法和对象方法). c.变量(包括成员变量.局部变量). 1. final修饰类: 用final修饰的类不能 ...

  3. pip安装报错 解决办法

    安装库时报错:Could not fetch URL https://pypi.python.org/simple/wheel/: 解决办法:  pip --trusted-host pypi.pyt ...

  4. Netty中的基本组件及关系

    原文:https://blog.csdn.net/summerZBH123/article/details/79344226---------------------  概述    这篇文章主要是用来 ...

  5. Linux 连接mysql

    连接MYSQL: 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL 找到mysql的安装目录,一般可以直接键入命令mysql -uroot -p,回车后提 ...

  6. 注册Docker Hub、以及Push(九)

      一.注册   1.使用浏览器打开官网的时候,发现注册按钮点不了       2.下载google访问助手,添加到浏览器         下载地址:http://www.ggfwzs.com/,根据 ...

  7. 商品分类选择 Jquery插件

    如果想要用此插件,请加微信: DS-valeb   说 category 插件索取 效果如下: 注意,一次性加载所有数据, 只适用小量,如果量大,请根据你的可行性来决择! 数据表设计结构如下: 调用如 ...

  8. 前端表单提交数据~php获取表单内容

    上图代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  9. excel表格公式无效、不生效的解决方案及常见问题、常用函数

    1.表格公式无效.不生效 使用公式时碰到了一个问题,那就是公式明明已经编辑好了,但是在单元格里不生效,直接把公式显示出来了,网上资料说有4种原因,但是我4种都不是,是第5种原因,如下图: 这种情况是由 ...

  10. 【rabbitmq】rabbitmq集群环境搭建

    安装rabbitmq-server 总共有3台虚拟机,都安装有rabbitmq服务,安装过程可参考: [rabbitmq]Centos7 下安装rabbitmq 创建用户和vhost 说明: 此步骤不 ...