千家信息网

Java中的方法内联怎么用

发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,这篇文章主要介绍"Java中的方法内联怎么用",在日常操作中,相信很多人在Java中的方法内联怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java中的方法内联怎
千家信息网最后更新 2024年11月29日Java中的方法内联怎么用

这篇文章主要介绍"Java中的方法内联怎么用",在日常操作中,相信很多人在Java中的方法内联怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java中的方法内联怎么用"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    1. 什么是方法内联

    例如有下面的原始代码:

    static class B {    int value;    final int get() {        return value;    }}public void foo() {    y = b.get();    // ...do stuff...    z = b.get();    sum = y + z;}

    我们首先要进行的就是方法内联,主要有下面两个目的:

    去除方法调用的成本,如查找方法版本、建立栈帧。

    为其他优化建立良好基础。

    内联后代码如下:

    public void foo() {    y = b.value;    // ...do stuff...    z = b.value;    sum = y + z;}

    后续,还可以进行冗余访问消除、复写传播、无用代码消除等优化操作。

    2. 方法内联的重要性

    方法内联是编译器最重要的优化手段,如果没有内联,多数其他优化都无法有效进行。例如下面这个例子:

    public static void foo(Object obj){    if (obj != null) {        System.out.println("do something");    }}public static void testInline(String[] args) {    Object obj = null;    foo(obj);}

    testInline()方法里其实全都是无用的代码,但是如果不做方法内联,就无法发现任何 Dead Code 的存在,因为分开看的话两个方法里面的操作可能都有意义。

    3. Java中方法内联的困难

    在 JVM 中,只有非虚方法,也就是使用invokespecial指令调用的私有方法、实例构造器、父类方法和使用invokestatic指令调用的静态方法才会在编译器进行解析。

    而其他虚方法被invokevirtual指令调用,在调用时必须进行方法接收者的多态选择。对于一个虚方法,编译器静态地去做内联的时候很难确定应该使用哪个方法版本,这就造成了方法内联的困难。

    继承类型关系分析 CHA

    首先,JVM 引入了一种名为类型继承关系分析 CHA 的技术,这种技术用于在已加载的类中,确定某个接口是否有多于一种的实现、某个类是否存在子类、某个子类是否覆盖了父类的某个虚方法等信息。

    编译器在进行内联时会分不同情况采取不同处理:

    如果是非虚方法,那么就直接进行内联。

    如果是虚方法,那么向 CHA 查询是否有多个目标版本可供选择。

    如果只有一个版本,就直接内联,称为守护内联。但由于 Java 程序动态连接,不知道什么时候就会加载到新的类型而改变 CHA 的结论,所以要留好逃生门,假如程序后续执行中加载了导致继承关系发生变化的新类,那么必须抛弃已经编译的代码,退回到解释状态进行执行,或者重新编译。

    如果有多个版本可供选择,那即时编译器使用内联缓存来缩减方法调用的开销。内联缓存是一个建立在目标方法正常入口之前的缓存。在未发生方法调用时,内联缓存为空。第一次调用发生后,缓存记录下方法接收者的版本信息,并且在每次进行调用前都检查版本。

    如果每次调用的方法接收者版本是一样的,那称为单态内联缓存,通过缓存来调用,相比不内联只多了一次类型判断的开销。如果出现方法接收者不一致的情况,就退化为超多态内联缓存,开销相当于真正查找虚方法表来进行方法分派。当缓存未命中的时候,大多数JVM的实现时退化成超多态内联缓存,也有一些JVM选择重写单态内联缓存,就是更新缓存为新的版本。这样做的好处是以后还可能会命中,坏处是可能白白浪费一个写的开销。

    到此,关于"Java中的方法内联怎么用"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    0