为什么将类定义为 final 可以提高 JVM 性能?

2022-09-01 00:35:51

引用自 http://sites.google.com/site/gson/gson-design-document

为什么Gson中的大多数课程都标记为最终课程?

虽然 Gson 通过提供可插拔的序列化程序和解串器提供了相当可扩展的体系结构,但 Gson 类并不是专门设计为可扩展的。提供非最终类将允许用户合法地扩展 Gson 类,然后期望该行为在所有后续修订版中都有效。我们选择通过将类标记为最终来限制此类用例,并等待一个好的用例出现以允许可扩展性。将类标记为最终类还有一个小好处,即为 Java 编译器和虚拟机提供了额外的优化机会。

为什么会这样?[如果我猜:JVM知道类是最终的,它不维护方法覆盖表?还有其他原因吗?

性能有什么好处?

这是否适用于频率实例化的类(POJO?)还是适用于持有者静态方法的类(实用程序类)?

定义为最终的方法理论上也可以提高性能吗?

有什么影响吗?

谢谢你,马克西姆。


答案 1

虚拟(重写)方法通常通过某种表(vtable)实现,该表最终是一个函数指针。每个方法调用都有必须通过该指针的开销。当类被标记为final时,所有方法都不能被覆盖,并且不再需要使用表 - 这更快。

某些虚拟机(如 HotSpot)可以更智能地执行操作,并知道何时未覆盖方法,并根据需要生成更快的代码。

以下是有关HotSpot的一些更具体的信息。还有一些一般信息。


答案 2

IBM developerWorks的一篇旧的,显然不再但仍然在很大程度上相关的文章,其中指出:

常见的感知是,声明类或方法 final 使得编译器更容易内联方法调用,但这种感知是不正确的(或者至少,大大夸大了)。

在编程时,final 类和方法可能会带来很大的不便 - 它们限制了重用现有代码和扩展现有类功能的选项。虽然有时一个类是有充分理由的,例如为了强制不可变性而成为最终类,但使用final的好处应该大于不便。性能增强几乎总是妥协良好的面向对象设计原则的坏理由,当性能增强很小或不存在时,这确实是一个糟糕的权衡。

另请参阅另一个问题的相关答案这里还讨论了 .Net 的等效问题。所以讨论,“最终的方法是否内联?在标题为“明天哪些优化将毫无用处”的问题上,这个问题出现在列表中。

还要注意,类与类的影响纠缠在一起。 方法。对于方法,您可能会获得一些性能优势(再次,我没有很好的参考),因为它可以提示JIT进行内联,否则它无法做到(或者不是那么简单)。当您标记类时,您会得到相同的效果,这意味着所有方法也突然成为最终方法。请注意,Sun / Oracle的人声称HotSpot通常可以在有或没有关键字的情况下执行此操作。拥有类本身是否有任何其他影响?finalfinalfinalfinalfinalfinal

作为参考,请链接到有关最终方法最终类的 JLS。


推荐