为什么不显式调用finalize()或启动垃圾回收器? [英] Why do you not explicitly call finalize() or start the garbage collector?

查看:126
本文介绍了为什么不显式调用finalize()或启动垃圾回收器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读这个问题后,我想起了当我被教授Java和告诉永远不要调用finalize()或运行垃圾回收器,因为这是一个你不需要担心的大黑盒子。有人可以将这个原因归结为几句话吗?我确信我可以阅读Sun在这个问题上的技术报告,但我认为一个很好的,简短的,简单的答案可以满足我的好奇心。

解决方案<简短的回答:Java垃圾回收是一个非常精细的工具。 System.gc()是一个大锤。

Java的堆被分成不同的世代,每个世代都是用不同的策略收集的。如果您将分析器附加到健康的应用程序中,您会发现它很少需要运行最昂贵的集合,因为大多数对象都被年轻一代中更快的复制收集器捕获。



直接调用System.gc(),虽然技术上不能保证做任何事情,但实际上会触发一个昂贵的,停止世界的完整堆集合。这几乎总是做错的事情。你认为你正在节省资源,但实际上你正在浪费它们,没有很好的理由,迫使Java重新检查所有活着的对象以防万一。



如果您在关键时刻出现GC暂停问题时,最好将JVM配置为使用并发标记/清除收集器,该收集器专门用于最大限度地减少暂停的时间,而不是试图将大锤带到问题中,只是打破它进一步。



你在想的Sun文档在这里: Java SE 6 HotSpot™虚拟机垃圾收集调优



(你可能不知道的另一件事:在你的对象上实现一个finalize()方法会让垃圾收集变慢。取两个 GC运行来收集对象:一个运行finalize(),另一个运行finalize()以确保对象在finalization过程中不被复活;其次,finalize()方法的对象必须被视为GC的特殊情况是因为它们必须单独收集,不能只是散装扔掉。)


After reading this question, I was reminded of when I was taught Java and told never to call finalize() or run the garbage collector because "it's a big black box that you never need to worry about". Can someone boil the reasoning for this down to a few sentences? I'm sure I could read a technical report from Sun on this matter, but I think a nice, short, simple answer would satisfy my curiosity.

解决方案

The short answer: Java garbage collection is a very finely tuned tool. System.gc() is a sledge-hammer.

Java's heap is divided into different generations, each of which is collected using a different strategy. If you attach a profiler to a healthy app, you'll see that it very rarely has to run the most expensive kinds of collections because most objects are caught by the faster copying collector in the young generation.

Calling System.gc() directly, while technically not guaranteed to do anything, in practice will trigger an expensive, stop-the-world full heap collection. This is almost always the wrong thing to do. You think you're saving resources, but you're actually wasting them for no good reason, forcing Java to recheck all your live objects "just in case".

If you are having problems with GC pauses during critical moments, you're better off configuring the JVM to use the concurrent mark/sweep collector, which was designed specifically to minimise time spent paused, than trying to take a sledgehammer to the problem and just breaking it further.

The Sun document you were thinking of is here: Java SE 6 HotSpot™ Virtual Machine Garbage Collection Tuning

(Another thing you might not know: implementing a finalize() method on your object makes garbage collection slower. Firstly, it will take two GC runs to collect the object: one to run finalize() and the next to ensure that the object wasn't resurrected during finalization. Secondly, objects with finalize() methods have to be treated as special cases by the GC because they have to be collected individually, they can't just be thrown away in bulk.)

这篇关于为什么不显式调用finalize()或启动垃圾回收器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆