Java 终结器对JVM性能的影响

Java 终结器对JVM性能的影响,java,finalizer,Java,Finalizer,根据,在.Net中, 终结器实际上更糟糕。除此之外,它们运行得很晚(这对于许多种类的资源来说确实是一个严重的问题),它们的功能也不太强大,因为它们只能执行析构函数中允许的操作的子集(例如,终结器不能可靠地使用其他对象,而析构函数可以),即使在编写子集终结器时,也很难正确编写。而且收集可终结对象的成本很高:每个可终结对象,以及从中可以访问的对象的潜在巨大图形,都会升级到下一代GC,这使得收集大量对象的成本更高 这是否也适用于JVM,特别是HotSpot?Java的终结器机制非常类似。 下面是一篇关

根据,在.Net中,

终结器实际上更糟糕。除此之外,它们运行得很晚(这对于许多种类的资源来说确实是一个严重的问题),它们的功能也不太强大,因为它们只能执行析构函数中允许的操作的子集(例如,终结器不能可靠地使用其他对象,而析构函数可以),即使在编写子集终结器时,也很难正确编写。而且收集可终结对象的成本很高:每个可终结对象,以及从中可以访问的对象的潜在巨大图形,都会升级到下一代GC,这使得收集大量对象的成本更高


这是否也适用于JVM,特别是HotSpot?

Java的终结器机制非常类似。 下面是一篇关于终结器的好文章:

Java的一般经验法则是不要使用它们。

是2004年的一条明确声明:

与没有终结器的对象相比,具有终结器的对象(具有非平凡的
finalize()
方法的对象)具有显著的开销,因此应谨慎使用。可终结对象的分配和收集速度都较慢。在分配时,JVM必须向垃圾收集器注册任何可终结对象,并且(至少在HotSpot JVM实现中)可终结对象必须遵循比大多数其他对象更慢的分配路径。类似地,可终结对象的收集速度也较慢。在回收可终结对象之前,至少需要两个垃圾收集周期(在最好的情况下),垃圾收集器必须做额外的工作才能调用终结器。结果是分配和收集对象的时间更长,垃圾收集器的压力也更大,因为不可访问的可终结对象使用的内存保留时间更长。再加上终结器不能保证在任何可预测的时间范围内运行,甚至根本不能运行,您可以看到,终结是正确使用的工具的情况相对较少


以下是有效Java第二版中的一些精选引用:第7项:避免终结器:

终结器是不可预测的,通常是危险的,通常是不必要的。它们的使用会导致行为不稳定、性能低下和可移植性问题。终结器的有效用途很少,[…]根据经验,您应该避免使用终结器

您应该真正确保,事实上,您确实需要终结器;大多数时候你不知道

请注意不要将终结器看作是C++的C++析构函数的java模拟程序。在C++中,析构函数是回收与对象相关的资源的正常方式,是构造函数的必要对应项。在Java中,当对象变得不可访问时,垃圾收集器会回收与该对象关联的存储,程序员无需特别努力。C++析构函数还用于回收其他非内存资源。在Java中,
try finally
块通常用于此目的

调用终结器时的语义也很重要:

Java编程语言没有指定调用
终结器的时间[…也没有指定哪个线程将调用任何给定对象的终结器]。[…]如果在终结过程中引发了未捕获的异常,则会忽略该异常并终止该对象的终结

此外,按需运行终结器的唯一机制被破坏。以下引用自有效的Java第二版:

[…]声称可以保证完成的唯一方法是
System.runFinalizersOnExit
及其邪恶的孪生兄弟
Runtime.runFinalizersOnExit
。这些方法存在致命缺陷,已被弃用

布洛赫进一步评论了绩效处罚(强调):

哦,还有一件事:使用终结器会造成严重的性能损失。在我的机器上,创建和销毁一个简单对象的时间大约为5.6ns。添加终结器会将时间增加到2400ns。换句话说,使用终结器创建和销毁对象的速度要慢430倍

关于基准测试方法的细节如此之少,我认为具体的数字意义不大,但它确实证实了广泛记录的事实:终结器非常昂贵

本书确实解释了使用终结器有效的罕见场景。此答案中省略这些引号是有意的。

当垃圾回收确定不再引用某个对象时,垃圾回收器会调用该对象。子类重写finalize方法以处置系统资源或执行其他清理

不要使用终结器,主要是因为它们不可预测,我们也不知道 何时执行“不要试图比JVM更聪明”


@Romain Hippeau:我很喜欢这篇12年前的文章:)事实上,我对这篇文章认为可以接受的用例很感兴趣:“但是你也可能希望包括一个终结器,它检查资源是否已经被释放,如果没有,就继续释放它。这样的终结器可以防止(希望不会鼓励)草率地使用课堂。”@Alexey-如果你真的需要为某件事使用终结器,那么即使它们相当昂贵,你也需要使用它们。它们没有那么昂贵……只要你不创建数千个可终结的对象。@Stephen C.如果你真的需要为某件事使用终结器,那么你需要做其他事情,因为没有担保请注意,终结器将完全运行。@NoozNooz42几年后,它将成为一篇已有20年历史的文章:(altou)