阅读完这个问题之后,我想起了什么时候教我Java的,并且告诉我永远不要调用finalize()或运行垃圾回收器,因为“这是一个大黑盒子,您无需担心”。有人可以将其理由简化为几句话吗?我敢肯定,我可以阅读Sun的有关此事的技术报告,但是我认为一个不错的,简短的简单答案将满足我的好奇心。
简短的答案:Java垃圾回收是一个非常精细的工具。System.gc()是大锤。
Java的堆分为不同的世代,每个世代都是使用不同的策略收集的。如果将事件探查器附加到运行状况良好的应用程序,您会发现它很少需要运行最昂贵的集合,因为大多数对象是年轻一代中更快的复制收集器捕获的。
直接调用System.gc(),尽管从技术上讲不能做任何事情,但实际上将触发昂贵的,停止运行的全堆收集。这 几乎总是错误的做法 。您以为自己在节省资源,但实际上却没有充分的理由浪费它们,因此迫使Java重新检查所有活动对象,以防万一。
如果您在关键时刻出现GC暂停问题,最好将JVM配置为使用并发标记/清除收集器,该收集器是专门为最大程度地减少暂停时间而设计的,而不是尝试使用大锤解决问题,并且进一步打破它。
您正在考虑的Sun文档在这里:Java SE 6 HotSpot™虚拟机垃圾收集调优
(您可能不知道的另一件事:在您的对象上实现finalize()方法会使垃圾回收变慢。首先,将运行 两次 GC来收集对象:一次运行finalize(),第二次运行以确保该对象不存在。其次,具有finalize()方法的对象必须由GC视为特殊情况,因为它们必须单独收集,不能将它们大量丢弃。)