优秀Java VM中方法调用的开销是多少?

有人能想出一个反汇编的机器码汇编列表吗?

我的意思是与C中的普通函数调用相比,必须有一些开销。

VM需要跟踪调用以查找热点,当它使用已编译的代码时,如果新加载的类需要重新编译,则需要提供更改已编译方法的方法。

我想在某处还有一个返回堆栈溢出检查。

编辑:我想我应该提一下,我不是一个java程序员,而是一个编译器编写器,想要找出为什么java应用程序如此缓慢而java微基准测试与本机编译代码相当。 因此,在这里查看一些细节对我来说很重要,即使他们只需要几个几纳秒和一些额外的指令。

Java不直接编译为机器代码,它编译为字节码,然后在运行时解释或编译为机器代码 – 我不知道如何在运行时获取机器代码,我只是想象它作为这个巨大的质量移动,改变字节,最终快速可靠地执行DAMN。

一个小方法调用应该在运行时完全编译。 如果可以解析或忽略足够的引用,即使是大型方法调用也可以由VM编写为内联机器代码。

使用Final可以提供很多帮助,因为它可以为VM提供有关如何进一步优化的提示。

由于方法调用实际上可以完全编译,并且最多只需要最小的成本 – 你真的不应该担心它。 当你有一个失败的性能规范时,只需编写最好的代码并担心性能问题(此时,优化点优于尝试消除代码中的方法调用,破坏相关人员的代码库)。

请注意,由于运行时分析,它在某些非常罕见的情况下实际上比C中的类似代码更快(c编译器不会在运行时进行分析并为您手动优化代码,您必须自己完成所有这些) 。

在更新的问题中,OP写道:

我想我应该提一下,我不是一个java程序员,而是一个编译器编写器,想要找出为什么java应用程序如此缓慢,而java微基准测试与本机编译代码相当。

然后在评论中,OP写道:

…我发现Java 1.3中的方法调用SUN VM(我用过的最后一个)非常昂贵,速度几乎加倍,因为内联显然远远不能完美。

我认为真正的问题是你认为“Java很慢”是基于Java 版本的经验。 自Java 1.3发布以来,Java JIT编译器在9年中得到了显着改进。

因此,在这里查看一些细节对我来说很重要,即使他们只需要几个几纳秒和一些额外的指令。

如果你(自己承认)不是一个java程序员,而是一个(非Java我假设的)编译器编写器,为什么这些细节对你很重要?

更新:我发现太阳维基上的这个页面可能会有所帮助。 它适用于仅作为开发版本提供的Java 7,但可能有足够的线索来帮助您为当前Java版本反汇编JIT编译代码。

好吧,我从来没有编程过Java 1.3,但我经常使用Eclipse,Netbeans和IntelliJ,而且与本机GUI程序相比,所有这些都是如此之慢。

我不确定我是否清楚如何生成GUI性能的统计数据 – 您是否测量执行特定任务所花费的时间,使用自动化测试,或者这是您排序的情况之一眼球它并说“它比程序X慢或快”。 我不是原生GUI程序的专家,但我知道Java中的GUI经常看起来很慢,不是因为Java本身必然很慢,而是因为GUI编写者无法构建响应式GUI – 将长时间运行的任务放在事件上一个例子,Dispatch Thread。 在缺乏构造良好的比较测试的情况下,很难说出Java的错误是什么,以及错误的GUI编程的错误是什么。

不过,为了回答你的问题,Bill K提到了计算机编程枪战游戏作为众多编译器基准测试的来源。 可以在此处找到Win32平台的另一个有趣的统计数据来源。

这在很大程度上取决于您使用的JVM(特别是在使用能够及时编译为本机代码的JVM时),因为对代码执行的优化最终将决定这一点。

例如,JVM可能决定内联您的方法,然后您根本没有调用开销。 如果方法没有内联,但仍然编译成本机代码,那么使用C / C ++中的指针调用方法/函数,加上特定于机器的需求(例如,设置堆栈stace,参数,结语/序幕)。 这应该总结一下执行10到30个本机指令的时间,但它是一个近似值 – 如果真的很重要,你应该测量它。

如果您使用仅解释JVM,数字应该是非常不同的,可能具有更高的开销(从未自己检查过,但如果我不得不猜测,我会赌一个额外的幅度 – 所以大约100到300个指令)。

这里的要点是你要比较苹果和橘子。 Java在运行时编译(你听说过JIT吗?),所以它与离线编译的C不完全可比。 大部分开销来自你不计入C(编译过程)的时间,而不是你想象的“方法调用”