JVM编译器优化技术

方法内联

方法内联就是把目标方法的代码原封不动地“复制”到发起调用的方法中,避免发生真实的方法调用。但是在java虚拟机中,只有使用invokespecial指令调用的私有方法、实例构造器、父类方法和使用invokestatic指令调用的静态方法是在编译期进行解析的,还有使用final修饰的方法可以确定唯一的版本。java中大多数方法调用都必须在运行时确定方法接收者的动态选择,他们的方法接受者可能多于一个。
为了解决虚方法内联问题,java虚拟机引入了类型继承关系分析(Class Hierarchy Analysis,CHA)的技术,用于确定目前已知的类当中,某个接口是否多余一个实现,某个类是否存在子类,某个子类是否覆盖了父类的某个虚方法等信息。如果是非虚方法,那么直接进行内联就可以了,这种内联关系时百分百安全保障的;如果遇到虚方法,则会向CHA此方法当前运行状态是否有多个目标版本可供选择,如果查到只有一个版本,那么就可以假设“运行程序的全貌就是现在运行的样子”来进行内联,这种内联被称为守护内联(Guarded Inlining);不过java程序时动态链接的,说不定什么时候会加载到新的类型从而改变CHA的结论,因此这种内联属于激进预测性能,必须预留好“逃生门”,当假设条件不成立的时的“退路”。运行的过程中,如果继承关系没有发生变化,内联代码可以一直运行下去,如果继承关系发生了变化,那么就会抛弃已编译的代码,返回到解释状态执行或重新进行编译。
如果CHA查找出来的方法确实有多个版本的可供选择,使用内联缓存(Inline cash)的方式缩减方法调用的开销。内联缓存是建立在目标方法正常入口之前的缓存,它的工作原理大致为:在为发生方法调用之前,内联缓存状态为空,当第一次调用发生的时候,缓存记录下方法调用的版本信息,并且每次方法调用的时都比较接收者的版本。如果每次调用方法接收者的版本一样,那么这是它是一种单态内敛缓存,比用内联的非虚方法仅多了一次判断的开销。若果出现接收者不一致的情况,就退化成超多态内联缓存。其开销相当于真正查找虚方法表的开销。

逃逸分析

逃逸分析的基本原理:分析对象的动态作用域,当一个对象定义在方法里面,它可能被外部方法引用,例如作为方法调用参数传递到其它方法中,这种称为方法逃逸。甚至还有可能被外部线程访问到,譬如赋给其它线程的中可访问的实例变量,这种称为线程逃逸;
如果能够证明一个对象不会逃逸到方法或线程之外,或者逃逸程度比较低(只逃逸出方法而不会逃逸出线程),则可能为这个对象实例采取不同程度的优化:

  • 栈上分配(Stack Allocations): 如果确认对象不会逃逸出线程之外,那么让这个对象在栈上分配内存将会是一个不错的注意,对象占用的空间就会随栈帧出栈而销毁。栈上分配只支持方法逃逸,不支持线程逃逸。
  • 标量替换(Scalar Replacement):如果一个数据已经无法在分解成更小的数据来表示了,Java虚拟机中的原始数据类型(int、long等数值类型及reference类型等)都不能在进一步分解,这些数据类型称为标量。相对的,如果一个数据可以继续分解,那它就被称为聚合量(Aggregte),java中的聚合量就是典型的聚合量。如果把一个对象拆散,根据程序的访问情况,将其用到的成员变量恢复为原始数据类型来访问,这个过程称为标量替换。假如逃逸分析能够证明一个对象不会被外部方法访问,并且这个对象可以被拆分,那么程序真正运行的时候可能不会去创建对象,而是改为直接创建它的若干个被这个方法使用的成员变量来代替。将对象拆分之后,除了可以让对象的成员变量在栈上(栈上存储数据,很大机会被虚拟机分配至物理机器上的告诉寄存器中存储)分配和读写之外,还可以为后续进一步的优化手段创建条件。标量替换可以视作栈上分配的一种特例。
  • 同步消除(Synchronization Elimination):线程的同步就是一个相对耗时的功能,如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其它线程访问,那么这个变量的读写肯定不会有竞争,这个变量实施的同步措施就可以安全地消除。

公共子表达式消除

如果一个表达式E之前已经被计算过了,并且从先前的计算到现在E中所有变量的值都没有变化,那么E的这次出现就称为公共子表达式。这种优化措施仅限于程序基本块内,便可称为局部公共子表达式消除。如果优化范围涵盖多个基本模块,那么就称为全局公共子表达式消除。

数组边界检查消除

如果编译器只要通过数据流分析可以判定循环变量的取值范围永远在区间[0,length]之内,那么循环中就可以把整个数组的上下界检查消除掉,这可以节省很多次的条件判断操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值