什么是Java 方法内联?

我们先来看看普遍的内联函数含义。在维基百科中解释为:

内联函数:在计算机科学中,内联函数(有时称作在线函数编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。


为什么要设计内联函数?

 其实也就两个字:性能。借用维基百科的解释:

内联扩展是一种特别的用于消除调用函数时所造成的固有时间消耗方法。一般用于能够快速执行的函数,因为在这种情况下函数调用的时间消耗显得更为突出。


方法调用开销?

Java中一个方法中调用不仅有执行方法逻辑的开销,还有一部分底层的开销,比如:方法栈帧的生成、局部变量的进栈与出栈、指令执行地址的跳转,所以需要在一些特定时候引入内联机制,减少底层的开销,从而提高运行性能。


我们举个

内联之前可能的样子:

public int  fun1(int a, int b){
return fun2(a, b);
}
public int fun2(int a, int b){
return a + b;
}

内联之后:

public int fun1(int a, int b){
return a + b;
}

这样内联之后减少了fun2栈帧的生成、fun2 局部变量进栈出栈操作,以及从fun1 到 fun2 指令执行的切换开销,可以给我们带来一定的性能开销,但是是不是这样就代表,我们所有的方法调用都可以使用方法内联来进行优化呢,很明显不可能,那么我们什么时候可以用方法内联来优化代码呢?我们接着看看


方法内联的时机

首先说下为什么不能时时都采用方法内联进行性能优化呢,主要原因为几点:

    1. 热点代码:即一个代码如果常常被我们调用到,那么才有必要进行内联优化,如果一个方法就调用一次,那么很明显没有必要进行优化
    1. 方法体大小:JVM 中被内联的方法会被编译到机器码放在code cache 中。如果方法体大,会影响缓存热点方法的个数,反而会影响性能。

从上面我们可知,影响方法内联的因素就是方法调用频率,以及方法大小。当然我们也可以进行JVM配置,强制指定哪些方法可以被内联。下面列举部分内敛规则:

部分内联规则:

  • 由 -XX:CompileCommand 中的 inline 指令指定的方法,以及由 @ForceInline 注解的方法(仅限于 JDK 内部方法),会被强制内联。 而由 -XX:CompileCommand 中的 dontinline 指令或 exclude 指令(表示不编译)指定的方法,以及由 @DontInline 注解的方法(仅限于 JDK 内部方法),则始终不会被内联。
  • 如果调用字节码对应的符号引用未被解析、目标方法所在的类未被初始化,或者目标方法是 native 方法,都将导致方法调用无法内联。
  • JVM决定一个方法是否是热的(例如。(频繁调用)基于内部计算;它不直接受任何可调参数的影响。如果一个方法由于频繁调用而符合内联条件,那么只有当它的字节码大小小于325字节(或者指定为-XX:MaxFreqInlineSize=N标志)时,它才会内联。否则,只有当它很小:小于35字节(或者指定为-XX:MaxInlineSize=N标志的值)时,它才有资格进行内联

    ...

当然方法内联还有很多限制,如下图:

Tips:java -XX:+PrintFlagsFinal 可通过这个命令查看JVM默认参数


Java 方法内联 和 C++ 函数内联区别
  • C++ 函数内联可通过inline进行声明,而Java 方法内联则由JVM控制,开发者无法控制
  • C++ 函数内联为编译时进行,而Java 方法内联则是由JIT在运行期进行

文章参考博客:

Java 方法内联的更多相关文章

  1. Java方法内联

    一.概念 方法内联就是把调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术   函数调用过程 1.首先会有个执行栈,存储它们的局部变量.方法名.动态连接 2.当一个方法 ...

  2. JVM 学习(二)Java 内存模型、方法内联、逃逸 --- 2019年4月

    1.Java 的内存模型 定义了 happens-before,如果同一个线程中,字节码的先后顺序,后者观测了前者的运行结果,那么就会按顺序执行. Java 线程之间的通信由 Java 内存模型控制. ...

  3. 深入理解java虚拟机(十四)正确利用 JVM 的方法内联

    在IntelliJ IDEA里面Ctrl+Alt+M用来拆分方法.选中一段代码,敲下这个组合,非常简单.Eclipse也用类似的快捷键,使用 Alt+Shift+M.我讨厌长的方法,提起这个下面这个方 ...

  4. Java中的方法内联

    Java中的方法内联 1. 什么是方法内联 例如有下面的原始代码: static class B { int value; final int get() { return value; } } pu ...

  5. jvm之方法内联优化

    前言 在日常中工作中,我们时不时会代码进行一些优化,比如用新的算法,简化计算逻辑,减少计算量等.对于java程序来说,除了开发者本身对代码优化之外,还有一个"人"也在背后默默的优化 ...

  6. C#效率优化(2)-- 方法内联

    一.JIT编译器可以通过将方法内联展开(Method Inline Expansion)来提升效率,类似C++中的内联函数(Inline Function),与C++的内联函数不同的是,C#并不支持内 ...

  7. 修改html内联样式的方法

    问题:如下图弹出页面操作不了 分析:审查元素,发现是内联元素样式z-index:19891015导致的,修改内联元素样式z-index:0发现可以操作了 解决方法:内联样式优先级高,再引入css覆盖样 ...

  8. C++ 内联(inline)函数

    目录 内联函数的使用方法 内联函数的使用规则 使用inline的时机 inline函数与宏函数的差异 inline是C++关键字,在函数声明或定义中,函数返回类型前加上关键字inline,即可以把函数 ...

  9. C#内联函数 特性 MethodImplOptions.AggressiveInlining)

    [MethodImpl(MethodImplOptions.AggressiveInlining)] 内联函数 Impl:implement的缩写 内联函数 在计算机科学中,内联函数(有时称作在线函数 ...

随机推荐

  1. 详细!Mybatis-plus常用API全套教程,我就不信你看完还不懂!

    前言 官网:Mybatis-plus官方文档 简化 MyBatis ! 创建数据库 数据库名为mybatis_plus 创建表 创建user表 DROP TABLE IF EXISTS user; C ...

  2. CDR魔镜插件是什么,有哪些功能?

    CDR魔镜插件是一款功能强大的CorelDRAW插件,很多CDR用户很早直接就有接触,因其强大的功能性和快速运行的特点被广大用户所喜爱,没有繁琐的选项,无论新人小白,还是制图高手都能够很快的适应,实现 ...

  3. 【Go语言绘图】gg 库的基本使用

    最近接了个比较大的需求,需要做很多图片处理的事情,比如图片的旋转裁截拼接,各种渐变处理,文字排列,一开始光是想想就头疼.但没有办法,既然已经需求已经到手上了,那就得把它做好才行,于是便开始被迫营业,无 ...

  4. Python机器学习笔记:异常点检测算法——LOF(Local Outiler Factor)

    完整代码及其数据,请移步小编的GitHub 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/MachineLearningNote 在数据挖掘方面,经常需 ...

  5. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人

    [NOIP2017提高A组模拟9.17]信仰是为了虚无之人 Description Input Output Sample Input 3 3 0 1 1 7 1 1 6 1 3 2 Sample O ...

  6. Robot Framework接口自动化案例分享⑦——Jenkins持续集成

    一.RobotFramework插件安装 1.Jenkins首页->系统管理->插件管理->可选插件-> 2.搜索robot,点击直接安装 二.任务参数配置 1.新建任务 Je ...

  7. 第10.4节 Python模块的弱封装机制

    一. 引言 Python模块可以为调用者提供模块内成员的访问和调用,但某些情况下, 因为某些成员可能有特殊访问规则等原因,并不适合将模块内所有成员都提供给调用者访问,此时模块可以类似类的封装机制类似的 ...

  8. PyQt(Python+Qt)学习随笔:QTreeView树形视图的expandsOnDoubleClick属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeView树形视图的expandsOnDoubleClick属性用于控制鼠标双击是否展开或折 ...

  9. 问题:PyCharm调试方法Force Step over与step over的区别

    Force Step over与step over的差别是,后者在执行到函数时,如果函数中设置了断点,会在该函数断点处暂停,等待进一步调试指令,而Force Step over不论函数中是否有断点,都 ...

  10. 解读 authentication.py

    """ Provides various authentication policies. """ import base64 import ...