什么是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. Guitar Pro教程之组织小节

    上一章节我们讲述了关于Guitar Pro 7的主界面的相关功能的介绍,对于初学作曲,又是吉他的初学者,刚刚接触{cms_selflink page='index' text='Guitar Pro' ...

  2. Linux高可用之Keepalived

    1: 安装keepalived yum install -y keepalived ipvsadm 安装keepalived和LVS管理软件ipvsadm 主机与备机都需要安装 ######修改配置文 ...

  3. GraphicsLab 之 Atmospheric Scattering (二)

    作者:i_dovelemon 日期:2020-11-25 主题:Atmospheric Scattering, Volume Scattering, Rayleigh Scattering, Mie ...

  4. DNS、IP地址、子网掩码和默认网关

    一.DNS服务器 DNS是指:域名服务器(Domain Name Server).在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转 ...

  5. CentOS 7搭建本地yum源

    问题 CentOS7.1安装rpm包时提示缺失包,有些包iso里面也没有,只能从外网yum,这种情况下,可以提前yum好所需的依赖包,做成一个本地yum源.将这些文件拷贝到没联网的机器就可以使用了. ...

  6. MIT-6.006算法导论(2011秋)

    L01 Algorithmic Thinking,Peak Finding 算法定义:高效处理大量数据的程序 在学本课之前最好先学习6.042,本课进阶为6.046 本门课的8个主要章节:算法思想.排 ...

  7. vs2019 Com组件初探-通过IDispatch接口调用Com

    vs2019 Com组件初探-简单的COM编写以及实现跨语言调用 上一篇实现了如何编写基于IDipatch接口的COM以及vbs如何调用编写的COM 本次主要是实现VBS的CreateObject函数 ...

  8. tomcat安装及环境变量配置

    java环境的配置应该都学过吧,这里简单的讲一下. 下载安装java JDK,注意安装的路径,我们需要进行环境变量的配置. 2 安装完成以后,配置环境变量 环境变量的配置这里就以win7为例:右击计算 ...

  9. 发现了一个关于 gin 1.3.0 框架的 bug

    gin 1.3.0 框架 http 响应数据错乱问题排查 问题概述 客户端同时发起多个http请求,gin接受到请求后,其中一个接口响应内容为空,另外一个接口响应内容包含接口1,接口2的响应内容,导致 ...

  10. 冰河教你一次性成功安装K8S集群(基于一主两从模式)

    写在前面 研究K8S有一段时间了,最开始学习K8S时,根据网上的教程安装K8S环境总是报错.所以,我就改变了学习策略,先不搞环境搭建了.先通过官网学习了K8S的整体架构,底层原理,又硬啃了一遍K8S源 ...