我试图检测我的一些Java代码以确保对象被正确地垃圾收集,并且我发现令人惊讶的是它并没有像我预期的那样经常被调用。
我现在想知道这是因为错误的仪器还是我需要解决的实际内存泄漏。 VisualVM分析器似乎表明了前者。
关注的情况是我有一个处理请求的线程,并且在请求中创建了数千个临时对象。有时,此线程写入的套接字意外关闭,线程遇到异常并死亡。
当线程死亡时,似乎不会在这些对象上调用.finalize()。这是不相信我的仪器的原因吗?
答案 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()
不是,则不应将其解释为“称有内存泄漏“。可能只是该对象不是 尚未 垃圾收集。
如果您正在寻找内存泄漏,请使用工具。见选项: