Java 方法内联
什么是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 指令执行的切换开销,可以给我们带来一定的性能开销,但是是不是这样就代表,我们所有的方法调用都可以使用方法内联来进行优化呢,很明显不可能,那么我们什么时候可以用方法内联来优化代码呢?我们接着看看
方法内联的时机
首先说下为什么不能时时都采用方法内联进行性能优化呢,主要原因为几点:
- 热点代码:即一个代码如果常常被我们调用到,那么才有必要进行内联优化,如果一个方法就调用一次,那么很明显没有必要进行优化
- 方法体大小: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 方法内联的更多相关文章
- Java方法内联
一.概念 方法内联就是把调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术 函数调用过程 1.首先会有个执行栈,存储它们的局部变量.方法名.动态连接 2.当一个方法 ...
- JVM 学习(二)Java 内存模型、方法内联、逃逸 --- 2019年4月
1.Java 的内存模型 定义了 happens-before,如果同一个线程中,字节码的先后顺序,后者观测了前者的运行结果,那么就会按顺序执行. Java 线程之间的通信由 Java 内存模型控制. ...
- 深入理解java虚拟机(十四)正确利用 JVM 的方法内联
在IntelliJ IDEA里面Ctrl+Alt+M用来拆分方法.选中一段代码,敲下这个组合,非常简单.Eclipse也用类似的快捷键,使用 Alt+Shift+M.我讨厌长的方法,提起这个下面这个方 ...
- Java中的方法内联
Java中的方法内联 1. 什么是方法内联 例如有下面的原始代码: static class B { int value; final int get() { return value; } } pu ...
- jvm之方法内联优化
前言 在日常中工作中,我们时不时会代码进行一些优化,比如用新的算法,简化计算逻辑,减少计算量等.对于java程序来说,除了开发者本身对代码优化之外,还有一个"人"也在背后默默的优化 ...
- C#效率优化(2)-- 方法内联
一.JIT编译器可以通过将方法内联展开(Method Inline Expansion)来提升效率,类似C++中的内联函数(Inline Function),与C++的内联函数不同的是,C#并不支持内 ...
- 修改html内联样式的方法
问题:如下图弹出页面操作不了 分析:审查元素,发现是内联元素样式z-index:19891015导致的,修改内联元素样式z-index:0发现可以操作了 解决方法:内联样式优先级高,再引入css覆盖样 ...
- C++ 内联(inline)函数
目录 内联函数的使用方法 内联函数的使用规则 使用inline的时机 inline函数与宏函数的差异 inline是C++关键字,在函数声明或定义中,函数返回类型前加上关键字inline,即可以把函数 ...
- C#内联函数 特性 MethodImplOptions.AggressiveInlining)
[MethodImpl(MethodImplOptions.AggressiveInlining)] 内联函数 Impl:implement的缩写 内联函数 在计算机科学中,内联函数(有时称作在线函数 ...
随机推荐
- 讲一讲Java的字符串常量池,看完你的思路就清晰了
前言 很多朋友Java的字符串常量池的概念困扰了很长一段时间,最近研究了一下jvm指令码,终于对它有了大概的了解. 在展示案例前,我们需要先搞清楚一个概念,众所周知,jvm的内存模型由程序计数器.虚拟 ...
- 如何用思维导图软件MindManager制作项目管理图表
项目管理的官方解释为:运用各种相关技能.方法与工具,为满足或超越项目有关各方对项目的要求与期望,所开展的各种计划.组织.领导.控制等方面的活动. 其实使用MindManager思维导图软件来创建项目管 ...
- Vue看板娘教程1.0
Live2D看板娘 前言(PS:本教程使用的Vue项目) 一.下载文件 二.使用步骤 1.引入文件 2.引入js 3.修改app.vue 4.如何换模型? 更换模型的效果 5.如何换语音? 结尾(后续 ...
- Redis 基础数据结构之一:string(字符串)
Redis 有 5 种基础数据结构,分别为:string (字符串).list (列表).set (集合).hash (哈希) 和 zset (有序集合),Redis存储数据的结构是键值对形式的. 首 ...
- 【Vue】VUE源码中的一些工具函数
Vue源码-工具方法 /* */ //Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性. var emptyObject = Object.freeze({}); // th ...
- 【模板】【P3605】【USACO17JAN】Promotion Counting 晋升者计数——动态开点和线段树合并(树状数组/主席树)
(题面来自Luogu) 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 1⋯N(1≤N≤100,000) 编号,把公司组织成一棵树 ...
- Mybatis入门及第一个Mybatis程序
Mybatis笔记整理 所需要的基础知识 JDBC Mysql Java基础 Maven Junit 框架:是有配置文件的.最好的方式:看官网文档 1.简介 1.1.什么是MyBatis 简介 什么是 ...
- ModelViewSet基础操作
1 安装DjangoRestFramework pip install djangorestframework==3.11.1 2.在settings.py中注册 INSTALLED_APPS = [ ...
- linux下gdb命令大全
感谢国内的ACM同行们的支持,今年应该会是难忘的一年,谢谢大家的帮助啦 gdb命令如下,记全!!!
- NOIp2020游记
Day 1 考点还是在南航,第三次去已经没有什么新鲜感了,满脑子都是NOIp能不能考好.考前奶了一波这次必考最短路,于是在试机的时候打了一遍Dij和SPFA的板子,信心满满的上场了. 考试右后方是Ki ...