为什么 JVM 仍然不支持尾部调用优化?
2022-08-31 10:39:26
诊断 Java 代码:提高 Java 代码的性能 (alt) 解释了为什么 JVM 不支持尾部调用优化。
但是,尽管众所周知如何将尾递归函数自动转换为简单的循环,但Java规范并不要求进行这种转换。据推测,它不是必需的一个原因是,一般来说,转换不能在面向对象的语言中静态地进行。相反,从尾递归函数到简单循环的转换必须由 JIT 编译器动态完成。
然后,它给出了一个不会转换的Java代码的示例。
因此,正如清单 3 中的示例所示,我们不能期望静态编译器在 Java 代码上执行尾递归转换,同时保留语言的语义。相反,我们必须依靠 JIT 的动态编译。根据 JVM 的不同,JIT 可能会或可能不会执行此操作。
然后,它给出了一个测试,您可以使用它来确定您的JIT是否这样做。
当然,由于这是一篇 IBM 论文,因此它包含一个插件:
我用几个Java SDK运行了这个程序,结果令人惊讶。在 1.3 版的 Sun 的 Hotspot JVM 上运行表明 Hotspot 不执行转换。在默认设置下,堆栈空间在我的计算机上会在不到一秒钟的时间内耗尽。另一方面,IBM的1.3版JVM没有问题,表明它确实以这种方式转换了代码。
我过去看到过在Java中不实现TCO(并且被视为困难)的一个原因是JVM中的权限模型对堆栈敏感,因此尾部调用必须处理安全性方面。
我相信这不是Clements和Felleisen [1] [2]的障碍,我很确定问题中提到的MLVM补丁也处理它。
我意识到这并不能回答你的问题;只是添加有趣的信息。