前言

在日常中工作中,我们时不时会代码进行一些优化,比如用新的算法,简化计算逻辑,减少计算量等。对于java程序来说,除了开发者本身对代码优化之外,还有一个"人"也在背后默默的优化我们的代码,这个"人"就是jvm。jvm会帮我们分析出热点代码,优化代码逻辑。其中jvm最常做的优化之一就是:方法内联优化。

方法内联

什么是方法内联?又可以叫做函数内联,java中方法可等同于其它语言中的函数。关于方法内联维基百科上面解释是:

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

简单通俗的讲就是把方法内部调用的其它方法的逻辑,嵌入到自身的方法中去,变成自身的一部分,之后不再调用该方法,从而节省调用函数带来的额外开支。

函数调用开销

之所以出现方法内联是因为函数调用除了执行自身逻辑的开销外,还有一些不为人知的额外开销。这部分额外的开销主要来自方法栈帧的生成、参数字段的压入、栈帧的弹出、还有指令执行地址的跳转。比如有下面这样代码:

public static void function_A(int a, int b){
//do something
function_B(a,b);
} public static void function_B(int c, int d){
//do something
} public static void main(String[] args){
function_A(1,2);
}

则代码的执行过程如下:

所以如果java中方法调用嵌套过多或者方法过多,这种额外的开销就越多。

试想一下想get/set这种方法调用:

public int getI() {
return i;
} public void setI(int i) {
this.i = i;
}

很可能自身执行逻辑的开销还比不上为了调用这个方法的额外开锁。如果类似的方法被频繁的调用,则真正相对执行效率就会很低,虽然这类方法的执行时间很短。这也是为什么jvm会在热点代码中执行方法内联的原因,这样的话就可以省去调用调用函数带来的额外开支。

这里举个内联的可能形式:

public int  add(int a, int b , int c, int d){
return add(a, b) + add(c, d);
} public int add(int a, int b){
return a + b;
}

内联之后:

public int  add(int a, int b , int c, int d){
return a + b + c + d;
}

这样除了本身的相加逻辑的开销,比内联前减少了二次调用函数带来的额外开销。

内联条件

一个方法如果满足以下条件就很可能被jvm内联。

1、热点代码。 如果一个方法的执行频率很高就表示优化的潜在价值就越大。那代码执行多少次才能确定为热点代码?这是根据编译器的编译模式来决定的。如果是客户端编译模式则次数是1500,服务端编译模式是10000。次数的大小可以通过-XX:CompileThreshold来调整。

2、方法体不能太大。jvm中被内联的方法会编译成机器码放在code cache中。如果方法体太大,则能缓存热点方法就少,反而会影响性能。

3、如果希望方法被内联,尽量用private、static、final修饰,这样jvm可以直接内联。如果是public、protected修饰方法jvm则需要进行类型判断,因为这些方法可以被子类继承和覆盖,jvm需要判断内联究竟内联是父类还是其中某个子类的方法。

所以了解jvm方法内联机制之后,会有助于我们工作中写出能让jvm更容易优化的代码,有助于提升程序的性能。

jvm之方法内联优化的更多相关文章

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

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

  2. Java 方法内联

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

  3. Java方法内联

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

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

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

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

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

  6. Java中的方法内联

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

  7. 一个关于内联优化和调用约定的Bug

    很久没有更新博客了(博客园怎么还不更新后台),前几天在写一个Linux 0.11的实验 [1] 时遇到了一个奇葩的Bug,就在这简单记录一下调试过程吧. 现象 这个实验要求在Linux 0.11中实现 ...

  8. Go 中的内联优化

    文讨论 Go 编译器是如何实现内联的以及这种优化方法如何影响你的 Go 代码. 请注意:本文重点讨论 gc,实际上是 golang.org 的 Go 编译器.讨论到的概念可以广泛用于其他 Go 编译器 ...

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

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

随机推荐

  1. 深度搜索---------Lake counting

    #include<iostream>#include<cstdio>#include<cstdlib>#define maxn 100char ch[maxn][m ...

  2. Vue开启gzip压缩文件

    在你的项目使用了Vue的路由懒加载.Vue使用CDN引用项目组件,减少项目体积 后,还是觉得项目加载速度慢,效果不尽如人意的时候,还有一个“瘦身项目”可以完成,那就是利用nginx和webpack来使 ...

  3. xss原理绕过防御个人总结

    xss原理 xss产生的原因是将恶意的html脚本代码插入web页面,底层原理和sql注入一样,都是因为js和php等都是解释性语言,会将输入的当做命令执行,所以可以注入恶意代码执行我们想要的内容 x ...

  4. 16 . Go之网络编程

    互联网的本质 两台计算机之间的通信与两个人打电话原理是一样的. # 1. 首先要通过各种物理连接介质连接 # 2. 找准确对方计算机(准确到软件)的位置 # 3. 通过统一的标准(一般子协议)进行数据 ...

  5. pandas 几个重要知识点

    将 NaN 替换成某一数值 使用 fillna dataframe.fillna(value = 'xxx',inplace=True) 删除某一个值 使用 drop dataframe.drop(1 ...

  6. Python更新列表

    Python更新列表: 使用索引下标进行更新: # 修改列表的第 6 个元素为 d lst = ['a','b','c',1,2,3] lst[5] = 'd' print(lst) # ['a', ...

  7. win10下visual studio code安装及mingw C/C++编译器配置,launch.json和task.json文件的配置

    快一年了,我竟然还有脸回来..... 过去一年,由于毕设.找工作的原因,发生太多变故,所以一直没更(最主要的原因还是毅力不够...),至于发生了什么事,以后想说的时候再更吧..依然是小白,下面说正事. ...

  8. kubernetes 中安装 heapster 问题

    step1: 在官网下载部署文件 https://github.com/kubernetes-retired/heapster/tree/master/deploy/kube-config/influ ...

  9. 004_go语言中的常量

    代码演示 package main import "fmt" import "math" const s string = "constant&quo ...

  10. Python 实现 T00ls 自动签到脚本(邮件+钉钉通知)

    T00ls 每日签到是可以获取 TuBi 的,由于常常忘记签到,导致损失了很多 TuBi .于是在 T00ls 论坛搜索了一下,发现有不少大佬都写了自己的签到脚本,签到功能实现.定时任务执行以及签到提 ...