你能指望.finalize()被调用吗?

时间:2011-10-24 17:27:01

标签: java garbage-collection

我试图检测我的一些Java代码以确保对象被正确地垃圾收集,并且我发现令人惊讶的是它并没有像我预期的那样经常被调用。

我现在想知道这是因为错误的仪器还是我需要解决的实际内存泄漏。 VisualVM分析器似乎表明了前者。

关注的情况是我有一个处理请求的线程,并且在请求中创建了数千个临时对象。有时,此线程写入的套接字意外关闭,线程遇到异常并死亡。

当线程死亡时,似乎不会在这些对象上调用.finalize()。这是不相信我的仪器的原因吗?

4 个答案:

答案 0 :(得分:4)

Finalize()不是解决方案。您无法知道何时会调用终结器。如果您的问题是异常,请使用try/catch/finally阻止并关闭/清除您要在finally块中关闭的所有内容。这保证了在两种情况下都会清理所有内容:逻辑正常终止或抛出异常。

答案 1 :(得分:2)

没有。无法保证会被调用。但是,它通常被称为。可能是您没有正确释放对象,或者垃圾收集器没有运行,或者终结器线程正在等待运行的好时机。

您可以在语言规范的Finalization of Class Instances部分阅读相关内容。

答案 2 :(得分:1)

根据我在Java基础知识上的所有内容,你应该从不依赖于finalize来运行。 finalize()是不是析构函数,你可能从其他语言中知道。

来自java.lang.Object javadoc:

The Java programming language does not guarantee which thread will invoke the finalize method for any given object.

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#finalize()

我看待事物的方式,可怕的终结应该只在您的应用中包含一些本机代码时使用。但即便如此,也要确保不要依赖它。

答案 3 :(得分:0)

您的困惑似乎是内存泄漏是否存在。您正试图通过查看是否已调用finalize()来确定此问题。如果是这样,那么检查是否存在内存泄漏是不正确的。

我们很清楚,在Java中,memory leaks主要是指对您不需要的对象的隐藏引用。

finalize()的目的是让开发人员有机会清理他自己的混乱(连接,流,......)。内存应该是JVM的混乱/头疼,并由GC清理。

简而言之,事实上“ GC保证在之前调用finalize()释放内存”,如果finalize()不是,则不应将其解释为“称有内存泄漏“。可能只是该对象不是 尚未 垃圾收集。

如果您正在寻找内存泄漏,请使用工具。见选项: