一、概念
方法内联就是把调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术
 
函数调用过程
1、首先会有个执行栈,存储它们的局部变量、方法名、动态连接
2、当一个方法被调用,一个新的栈帧会被加到栈顶,分配的本地变量和参数会存储在这个栈帧
3、跳转到目标方法代码执行
4、方法返回的时候,本地方法和参数被销毁,栈顶被移除
5、返回原来的地址执行
 
注:这就是通常说的函数调用的压栈和出栈过程,因此,函数调用需要有一定的时间开销和空间开销,当一个方法体不大,但又频繁被调用时,这个时间和空间开销会相对变得很大,变得非常不划算,同时降低了程序的性能。根据二八原则,80%的性能消耗其实是发生在20%的代码上,对热点代码的针对性优化可以提升整体系统的性能
 
二、方法内联的原理
就如上面所说,就是把调用方函数代码"复制"到调用方函数中
 
看如下例子:
  1. private int add2(int x1 , int x2 , int x3 , int x4) {
  2. return add1(x1 , x2) + add1(x3,x4);
  3. }
  4.  
  5. private int add1(int x1 , int x2) {
  6. return x1 + x2;
  7. }

  

 
运行一段时间后,代码被内联翻译成:
  1. private int add2(int x1 , int x2 , int x3 , int x4) {
  2. //return add1(x1 , x2) + add1(x3,x4);
  3. return x1 + x2 + x3 + x4;
  4. }
 
三、方法内联的条件
JVM会自动的识别热点方法,并对它们使用方法内联优化。那么一段代码需要执行多少次才会触发JIT优化呢?通常这个值由-XX:CompileThreshold参数进行设置:
  使用client编译器时,默认为1500;
    使用server编译器时,默认为10000;
但是一个方法就算被JVM标注成为热点方法,JVM仍然不一定会对它做方法内联优化。其中有个比较常见的原因就是这个方法体太大了,分为两种情况。
   如果方法是经常执行的,默认情况下,方法大小小于325字节的都会进行内联(可以通过** -XX:MaxFreqInlineSize=N**来设置这个大小)
       如果方法不是经常执行的,默认情况下,方法大小小于35字节才会进行内联(可以通过** -XX:MaxInlineSize=N **来设置这个大小)
 
我们可以通过增加这个大小,以便更多的方法可以进行内联;但是除非能够显著提升性能,否则不推荐修改这个参数。因为更大的方法体会导致代码内存占用更多,更少的热点方法会被缓存,最终的效果不一定好。
 
JVM参数:(-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining)
当我们执行1000次
 

当我们执行10001次

 
四、内联的隐藏条件
 
虽然JIT号称可以针对代码全局的运行情况而优化,但是JIT对一个方法内联之后,还是可能因为方法被继承,导致需要类型检查而没有达到性能的效果
想要对热点的方法使用上内联的优化方法,最好尽量使用final、private、static这些修饰符修饰方法,避免方法因为继承,导致需要额外的类型检查,而出现效果不好情况。
 
五、结论
 
1、针对热点方法,想要通过JIT内联优化来提升性能的建议 
2、更小的方法体,JVM总是偏好更小的方法。
3、尽量使用final、private、static修饰符
4、使用+PrintInlining参数校验效果(【PrintInlining】-XX:+UnlockDiagnosticVMOptions必须配合参数{2}使用,并且只能加在其后才能生效)

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

  1. Java 方法内联

    什么是Java 方法内联? 我们先来看看普遍的内联函数含义.在维基百科中解释为: 内联函数:在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函 ...

  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. 【LeetCode】372. Super Pow 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/super-po ...

  2. C. Unfair Poll

    http://codeforces.com/problemset/problem/758/C C. Unfair Poll time limit per test 1 second memory li ...

  3. 圆桌问题(hdu4841)

    圆桌问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submi ...

  4. Certified Adversarial Robustness via Randomized Smoothing

    目录 概 主要内容 定理1 代码 Cohen J., Rosenfeld E., Kolter J. Certified Adversarial Robustness via Randomized S ...

  5. Spring Boot 2 中的默认日志管理与 Logback 配置详解

    Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为Java Util Logging .Log4J2 和Logb ...

  6. Mybatis源码系列 执行流程(一)

    1.Mybatis的使用 public static void main(String[] args) throws IOException { //1.获取配置文件流 InputStream is ...

  7. 微信支付 V3 RSA 加签踩坑

    最近在做微信支付,根据微信官方文档上的要求 用RSA加签去请求支付窗口的调起,下面详细列举支付开发过程: 当前项目的流程大概是,前端根据后端要求提交数据------->拿到后台返回的prepay ...

  8. Canvas原生API(纯CPU)计算并渲染三维图

    Canvas原生API(纯CPU)计算并渲染三维图 前端工程师学图形学:Games101 第三次作业 利用Canvas画三维中的三角形并使用超采样实现抗锯齿 最终完成功能 Canvas 原生API实现 ...

  9. Selenium_环境安装(1)

    Selenium是一个用于Web应用程序自动化测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样. Selenium基本上支持主流的浏览器,包括IE,Mozilla Firef ...

  10. CentOS7 常用命令汇总

    原文链接:https://blog.csdn.net/weixin_42208959/article/details/107970958 目录常用命令1.进程相关命令1.1 查询进程和结束进程1.2 ...