java调用怎么调用方法区_Java中的方法调用有多昂贵
java调用怎么调用方法区
我们都去过那儿。 在查看设计不良的代码的同时,听听作者对人们永远不应该牺牲性能而不是设计的解释。 而且,您不能说服作者摆脱其500行方法,因为链接方法调用会破坏性能。
好吧,这可能在1996年左右是正确的。 但是自那时以来, JVM已经发展成为一款了不起的软件。 找出它的一种方法是开始更深入地研究虚拟机执行的优化。 JVM应用的技术库非常广泛,但是让我们更详细地研究其中一种。 即方法内联 。 通过以下示例最容易解释:
int sum(int a, int b, int c, int d) {return sum(sum(a, b),sum(c, d));
}int sum(int a, int b) {return a + b;
}
当运行此代码时, JVM将弄清楚它可以用更有效的所谓“内联”代码代替:
int sum(int a, int b, int c, int d) {return a + b + c + d;
}
您必须注意,此优化是由虚拟机而不是由编译器完成的。 最初做出此决定的原因并不透明。 毕竟-如果您查看上面的示例代码-为什么在编译时可以推迟优化以产生更有效的字节码? 但是,考虑到其他不太明显的情况,JVM是执行优化的最佳位置:
- JVM除了静态分析外还配备了运行时数据。 在运行时,JVM可以根据最常执行的方法,冗余的负载,何时安全使用副本传播等做出更好的决策。
- JVM已获得有关基础体系结构的信息-内核数,堆大小和配置,因此可以根据此信息进行最佳选择。
但是,让我们在实践中看到这些假设。 我创建了一个小型测试应用程序 ,它使用几种不同的方法将1024个整数加在一起。
- 相对合理的一种,其中实现仅对包含1024个整数的数组进行迭代,并将结果求和。 InlineSummarizer.java中提供了此实现。
- 基于递归的分而治之方法。 我采用原始的1024个元素数组,然后将其递归分为两半,因此第一个递归深度为我提供了两个512个元素数组,第二个深度为四个256个元素数组,依此类推。 为了将所有1024个元素加在一起,我引入了1023个附加的方法调用。 此实现作为RecursiveSummarizer.java附加。
- 天真的分而治之的方法。 这也划分了原始的1024个元素的数组,但是通过在分开的两半上调用其他实例方法–即,我嵌套了sum512(),sum256(),sum128(),…,sum2()调用,直到我总结了所有元素。 与递归一样,我在源代码中介绍了1023个其他方法调用。
我有一个测试班来运行所有这些示例。 最初的结果来自未优化的代码:
从上面可以看出,内联代码是最快的。 而我们引入了1023个附加方法调用的方法则要慢25,000ns。 但是,此图像必须加以警告-它是JIT尚未完全优化代码的运行快照。 在我2010年中期的MB Pro中,根据实施情况,运行了200到3000次。
更现实的结果如下。 我已经运行了所有汇总器实现超过1,000,000次,并丢弃了JIT尚未成功执行的运行。
我们可以看到,即使内联代码仍然表现最佳,但迭代方法也以相当快的速度飞速发展。 但是递归明显不同–当迭代方法仅以20%的开销关闭时,RecursiveSummarizer会花费内联代码需要完成的340%的时间。 显然,这是应该注意的事情–使用递归时,JVM是无助的,无法内联方法调用。 因此,在使用递归时请注意此限制。
除了递归-方法开销几乎不存在。 源代码中有1023个其他方法调用之间的时间差仅为205 ns。 请记住,那是我们用于测量的那纳秒(10 ^ -9 s)。 因此,借助JIT,我们可以安全地忽略方法调用带来的大部分开销。 下次当您的同事将糟糕的设计决策隐藏在通过调用堆栈弹出效率不高的声明后面时,请让他首先完成一个小的JIT崩溃过程 。 如果您希望有能力阻止他将来的荒唐言论,请订阅我们的RSS或Twitter提要,我们很高兴为您提供未来的案例研究。
全面披露:本文中使用的测试用例的灵感是由Tomasz Nurkiewicz 博客文章触发的。
参考: Plumbr博客博客上的JCG合作伙伴 Nikita Salnikov Tarnovski 用Java进行方法调用的成本是多少 ?
翻译自: https://www.javacodegeeks.com/2013/02/how-expensive-is-a-method-call-in-java.html
java调用怎么调用方法区
java调用怎么调用方法区_Java中的方法调用有多昂贵相关推荐
- java堆栈方法区_java 栈 ,堆, 方法区
栈的特点如下: 1. 栈描述的是方法执行的内存模型.每个方法被调用都会创建一个栈帧(存储局部变量.操作数.方法出口等) 2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数.局部变 ...
- java 方法大全_java中的方法大全
方法: 一.什么是方法? 就是有名字的代码段.适用于函数. 方法的定义只管某个功能的实现,只保证功能的可用. 二.方法的目的是什么? 为了代码的重用.(相同的类型的操作,不用重复的写代码) 三.方法的 ...
- java语言的多态性及特点_Java中的方法的多态性有两种形式:( )和( )。_学小易找答案...
[填空题]已知函数 ,则微分 . [填空题]. [单选题]71.用转动小滑板法车圆锥时产生( )误差的原因是小滑板转动角度计算错误. [单选题] [填空题]Java中的方法的多态性有两种形式:( )和 ...
- java用递归删除文件夹_Java中通过递归调用删除文件夹下所有文件
摘自 : http://blog.sina.com.cn/s/blog_79333b2c0100xiu4.html import java.io.File; public class FileTest ...
- java native方法体在哪_java中native方法的使用
native關鍵字說明其修飾的方法是一個原生態方法,方法對應的實現不是在當前文件,而是在用其他語言(如C和C++)實現的文件中.Java語言本身不能對操作系統底層進行訪問和操作,但是可以通過JNI接口 ...
- java常量池方法区_Java方法区和运行时常量池溢出问题分析
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
- java定义一个类显示没有_Java 中的每个类都至少有一个构造方法,一个类中如果没有定义构造方法,系统会自动为这个类创建一个默认的构造方法。_学小易找答案...
[单选题]关于 Java 语言叙述错误的是( ). [判断题]类中 static 修饰的变量或方法,可以使用类名或对象的引用变量访问. [命名题]命名下列化合物, [单选题]急性胰腺炎的主要临床表现是 ...
- 2021-02-23关于java的方法区,为什么叫方法区,是否与实际用途相悖?
关于java的方法区,为什么叫方法区,是否与实际用途相悖? 在java中,栈中存放的是用来保存方法运行时状态的栈帧,存储了局部变量表,操作数栈等,而方法区存放的是已加载的类的基本信息.常量.静态变量等 ...
- java什么是栈和堆_JAVA中的栈和堆
JAVA在程序运行时,在内存中划分5片空间进行数据的存储.分别是:1:寄存器.2:本地方法区.3:方法区.4:栈.5:堆. 基本,栈stack和堆heap这两个概念很重要,不了解清楚,后面就不用学了. ...
最新文章
- LeetCode简单题之判断字符串的两半是否相似
- iOS-直播开发(开发从底层做起)
- 只会高中数学运算就能发现算法?Google开源的AutoML-Zero有多厉害
- 高手过招, 为什么 Redis Cluster 是16384个槽位?
- 卡巴斯基工业基础设施专用网络安全解决方案
- windows下多进程加协程并发模式
- C# 对get和set的理解
- 一文快速了解oCPX
- 中国剩余定理及其拓展
- Linux—vi/vim全局替换
- 【Flink】Insufficient number of network buffers required but only available
- Secure DevOps!探真科技2022云原生安全产品发布会圆满落幕
- 【转】ASP.NET AJAX入门系列(8):使用ScriptManager控件
- 数据挖掘概念与技术(韩家伟)阅读笔记5--数据规范化和属性构造
- SQL Server数据库优化的几种方法.
- 【C++课程设计】基于单向链表的通讯录管理程序
- 记一次:java实现excel转图片
- 编程语言的分类,以及网络瓶颈效应
- C判断tic tac toe输赢
- 将12小时制改为24小时制