2017-10-12 137 views
1

在我的理解(根据https://www.javaworld.com/article/2076949/learn-java/how-the-java-virtual-machine-handles-method-invocation-and-return.html?page=2)时,JVM处理方法调用如下: 从呼叫者创建被叫 流行论点新的堆栈帧,把它们的被调用 执行被叫方。的Java方法调用堆栈复制

但是,为什么我们必须将参数从一个堆栈复制/移动到另一个?

为被调用者创建一个新的重叠栈帧是不是更容易,因此调用者的最上面的槽(包含参数)现在是被调用者栈帧的最底部槽。只要我们事后清理所有东西(通过弹出),它不应该有所作为,但可以通过避免复制来提高方法调用的效率。

那么,这是什么问题,为什么我们不这样做呢?

回答

2

你引用的部分描述了一个正式的过程。该实现必须与该描述兼容,但不一定非得像这样。

如果你只是读了几句话以后,你会发现:

JVM规范不需要Java堆栈特定的实现。帧可以从一个堆中单独分配,也可以从连续内存中取出,或者两者兼而有之。

这就解释了为什么不是每个实施可以优化它就像你的建议,但

如果两帧是连续的,但是,虚拟机可以只重叠它们,这样的操作数堆栈的顶部一帧形成下一个局部变量的底部。在这种方案中,虚拟机不需要将objectref和args从一个帧复制到另一个帧,因为两个帧重叠。调用方法框架中包含objectref的操作数堆栈字将与新框架的局部变量0具有相同的内存位置。

所以没人说,它不会按照您的建议实施,实际上,这个优化机会已经被明确提及。但是本文没有讨论哪个具体的JVM以哪种方式实现堆栈。

也值得记住,对于优化的热点,调用协议可能完全不同,如果不是被调用者被内联到调用者中,它将完全移除所有调用工件。