如何判断Java对象的内存何时发布?

时间:2010-08-11 17:14:59

标签: java memory

我有一个Swing浏览器应用程序,其中包含一个错误,当我向GUI添加/删除内存时,没有为这些对象释放内存,而我正在尝试追踪保留它们的内容。问题是我不知道如何判断什么东西实际上是从记忆中完全释放出来的。

有没有办法判断对象是否已从内存中释放?我已经习惯了Objective-C,有几种方法可以告诉你。

由于

4 个答案:

答案 0 :(得分:6)

你无法在Java中真正做到这一点。所有提到终结者的答案都不是你想要的。

您可以做的最好的事情是将一个PhantomReference排入ReferenceQueue并民意调查,直到您获得参考。

final ReferenceQueue rq = new ReferenceQueue();
final PhantomReference phantom = new PhantomReference( referenceToObjectYouWantToTrack, rq );

你想在这里阅读Peter Kofler的答案(它解释了PhantomReference是什么):

Have you ever used Phantom reference in any project?

非常有趣的读到这里:

http://www.kdgregory.com/index.php?page=java.refobj

基本上,我在一个项目中使用PhantomReference,在安装软件时需要计算一次非常特殊的缓存。为了有效地计算这个(基于磁盘的)缓存,需要大量的内存(越多越好)。当释放大量内存时,我正在使用PhantomReference跟踪“几乎完全”。

答案 1 :(得分:3)

修改

正如NoozNooz42指出的那样,PhantomReference可以完成终结器所能做的一切,而不会出现问题终结器。因此,我鼓励使用PhantomReferences而不是finalize()。我保留原帖,因为我认为Java程序员至少应该知道finalize()存在。

原帖:

每个Java类都有一个finalize()方法,当没有其他对象持有对该类的引用时,该方法就会运行。您可以像这样扩展此方法:

protected void finalize() throws Throwable {
    try {
        // Do whatever you want
    } finally {
        super.finalize();
    }
}

通过这样做,您可以确定是否有任何内容存在对相关对象的引用。如果您使用此方法,请确保始终致电super.finalize()

关于最终确定的参考:

http://java.sun.com/developer/technicalArticles/javase/finalization/

答案 2 :(得分:3)

有多种方法可以检测内存泄漏。这是我目前想到的三个:

  1. 将Profiler附加到您的应用程序(NetbeansEclipse TPTP应该非常有用)
  2. 进行堆转储并分析(使用Eclipse Memory Analyzer)类的哪些实例在内存中被其他实例保存。
  3. 附加VisualVM以跟踪垃圾收集状态。

答案 3 :(得分:1)

试试YourKit。它是一个Java分析器,可以向您显示您的内存使用情况以及发生了什么。 IIRC,免费试用版可以与Eclipse集成,并具有所有付费版本的功能(它只有一个时间限制)。