Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何判断Java对象';谁的内存被释放了?_Java_Memory - Fatal编程技术网

如何判断Java对象';谁的内存被释放了?

如何判断Java对象';谁的内存被释放了?,java,memory,Java,Memory,我有一个Swing浏览器应用程序,它有一个bug,当我在GUI中添加/删除这些对象时,这些对象的内存并没有释放出来,我正试图跟踪它们的内存。问题是我不知道如何判断什么时候一些东西已经从记忆中完全释放出来了 有没有办法判断某个对象是否已从内存中释放?我已经习惯了Objective-C,其中有几种方法可以判断 谢谢编辑: 正如NoozNooz42所指出的那样,PhantomReference可以做终结器所能做的一切,而终结器不会出现问题。因此,我鼓励使用PhantomReferences过度扩展fi

我有一个Swing浏览器应用程序,它有一个bug,当我在GUI中添加/删除这些对象时,这些对象的内存并没有释放出来,我正试图跟踪它们的内存。问题是我不知道如何判断什么时候一些东西已经从记忆中完全释放出来了

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

谢谢

编辑:

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

原创帖子:

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

protected void finalize() throws Throwable {
    try {
        // Do whatever you want
    } finally {
        super.finalize();
    }
}
通过这样做,您可以确定是否有任何内容包含对相关对象的引用。如果使用这种方法,请确保始终调用
super.finalize()

定稿参考:


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

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

  • 将探查器附加到您的应用程序(或者在这里应该很有用)
  • 进行堆转储并分析(使用)一个类的哪些实例由哪些其他实例保存在内存中
  • 正在附加以跟踪垃圾回收状态

  • 你不能用Java真的做到这一点。所有提到终结器的答案都不是你想要的

    最好将PhantomReference放入ReferenceQueue并轮询,直到获得引用为止

    final ReferenceQueue rq = new ReferenceQueue();
    final PhantomReference phantom = new PhantomReference( referenceToObjectYouWantToTrack, rq );
    
    你想在这里阅读彼得·科夫勒的答案(它解释了什么是幻影参考):

    非常有趣,请阅读这里:


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

    在Java中应该避免使用终结器,因为它们不能保证真正收集对象的时间。此外,仅当实例符合收集条件时,finalize才起作用。通常有问题的对象由其他实例保存在内存中,所以最终确定没有帮助。另请参见此处:(Josh Bloch提供的有效Java)@jwachter:这一点很好,但您的链接需要登录才能阅读。@Justin Ardini:终结发生在对象被GC’ed之前。请参见我的答案:OP在PhantomReference之后,而不是终结器。最初阅读时,finalize()听起来像是obj-c中的dealoc(),但现在我不确定。垃圾收集是否调用finalize(),即在finalize()中放入System.out.println(“finalize”)表示正在收集该对象?谢谢Justin,这说明了这一点,但问题没有提到任何内存泄漏。OP只想跟踪对象何时被GC’ed。不幸的是,我的小程序从未使用过#1,也不知道为什么。我还将查看VisualVM,目前正在试用您的工具包。@NoozNooz42您是对的。但是我想你通常只会在有记忆问题的时候才去寻找收集到的东西。(FWIW,通常是一个监听器。)我想可能是的,但我尝试删除了所有ActionListener和ComponentListener良好的信息和链接,看起来Peter建议使用探查器。既然终结器可以解决PhantomReferences无法解决的问题,我更新了我的答案。我确实认为终结器对于OP试图做的事情来说“足够好”,但我意识到我不应该鼓励使用半弃用的技术。到目前为止,我尝试的分析器没有显示是否发布了单个对象的分辨率。看起来这个答案(PhantomReferences)可能是最好的工具,但我很难找到一个例子来说明如何使用它只跟踪发布的对象。kdgregory的示例是使用它跟踪SQL连接。我究竟是在轮询null值、referenceQueue还是其他一些跟踪列表?