维护一个所有权层次结构有助于不至于失去控制,其中每个资源拥有它获得的资源并负责释放它们。这个规则的结果是,每个不能由垃圾收集单独收集的资源(即这样的资源,它直接或间接拥有不能由垃圾收集释放的资源)必须提供某种生命周期支持,比如 close()
方法。
如果说平台库提供终结器来清除打开的文件句柄,这大大降低了忘记显式地关闭这些句柄的风险,为什么不更多地使用终结器呢?原因有很多,最重要的一个原因是,终结器很难正确编写(并且很容易编写错)。终结器不仅难以编写正确,终结的定时也是不确定的,并且不能保证终结器最终会运行。并且终结还为可终结对象的实例化和垃圾收集带来了开销。不要依赖于终结器作为释放资源的主要方式。
finally
块来释放该资源,但是长期存活的资源需要一种策略来确保它们最终被释放。对于任何一个这样的对象,即它直接或间接拥有一个需要显式释放的对象,您必须提供生命周期方法 —— 比如 close()
、release()
、destroy()
等 —— 来确保可靠的清除。
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- Concurrent Programming in Java(Doug Lea, Addison-Wesley, 1999):Doug Lea 的大部头作品中的第 3.4.1.3 节讨论了使用信号量来绑定集合的过程。
- “用弱引用堵住内存泄漏”(Brian Goetz, developerWorks, 2005 年 11 月):Brian 讨论了弱引用如何使得表达对象生命周期很容易。
- “Finalization, Threads, and the Java Memory Model”(Sun Developer Network, Hans Boehm):了解终结器有多难对付。
- Java 理论与实践:Brian Goetz 的完整系列。
- Java 技术专区:数百篇关于 Java 编程各方面的文章。
获得产品和技术
- Alice's Restaurant(Warner Brothers, 1969):从电影中了解 Arlo Guthrie 的整个经典民歌 “Alice's Restaurant Massacre”。