【问题标题】:java garbage collector - "get" the deleted objectsjava垃圾收集器-“获取”已删除的对象
【发布时间】:2012-01-19 09:29:59
【问题描述】:

是否有可能查看垃圾收集器将删除哪些对象?我不需要对象的内容,但对象的类是必需的。

我尝试编写一个实时应用程序,它创建和删除大量对象,一段时间后应用程序变慢。目前我不确定这是我的代码问题还是外部库的问题。如此完美的输出将标识所有已删除的类以及它们的“计数”(已删除了多少对象)。

我希望有人可以帮助我。

最好, 迈克尔

【问题讨论】:

  • 我会使用内存分析器。这可以向您显示对象的分配位置以及保留它们的原因(这可能是速度变慢的原因)。我使用 YourKit 是因为它更易于使用且功能更强大。 VisualVM 是免费的。

标签: java garbage-collection


【解决方案1】:

您可以尝试使用 VisualVM 监控您的应用程序。有一个插件可以提供有关垃圾收集器活动的信息。

http://visualvm.java.net/plugins.html

【讨论】:

  • 顺便说一句:Visualvm 也包含在 JDK 中:jdk..../bin/jvisualvm.exe (for windows)
【解决方案2】:

如何为您的对象覆盖finalize 方法并在那里记录类的名称?但请注意,这可能会阻止对象被垃圾收集。

你的班级可能看起来像这样:

public class MyObject {

    @Override
    public void finalize() throws Throwable {
        logger.debug("Object of class {} being garbage collected", this.getClass().getName());
    }
}

这是Object.finalize() 方法签名和文档。

/**
 * Called by the garbage collector on an object when garbage collection
 * determines that there are no more references to the object.
 * A subclass overrides the <code>finalize</code> method to dispose of
 * system resources or to perform other cleanup. 
 * <p>
 * The general contract of <tt>finalize</tt> is that it is invoked 
 * if and when the Java<font size="-2"><sup>TM</sup></font> virtual 
 * machine has determined that there is no longer any
 * means by which this object can be accessed by any thread that has
 * not yet died, except as a result of an action taken by the
 * finalization of some other object or class which is ready to be
 * finalized. The <tt>finalize</tt> method may take any action, including
 * making this object available again to other threads; the usual purpose
 * of <tt>finalize</tt>, however, is to perform cleanup actions before 
 * the object is irrevocably discarded. For example, the finalize method 
 * for an object that represents an input/output connection might perform
 * explicit I/O transactions to break the connection before the object is
 * permanently discarded. 
 * <p>
 * The <tt>finalize</tt> method of class <tt>Object</tt> performs no 
 * special action; it simply returns normally. Subclasses of 
 * <tt>Object</tt> may override this definition.
 * <p>
 * The Java programming language does not guarantee which thread will 
 * invoke the <tt>finalize</tt> method for any given object. It is 
 * guaranteed, however, that the thread that invokes finalize will not 
 * be holding any user-visible synchronization locks when finalize is 
 * invoked. If an uncaught exception is thrown by the finalize method, 
 * the exception is ignored and finalization of that object terminates.
 * <p>
 * After the <tt>finalize</tt> method has been invoked for an object, no 
 * further action is taken until the Java virtual machine has again 
 * determined that there is no longer any means by which this object can 
 * be accessed by any thread that has not yet died, including possible
 * actions by other objects or classes which are ready to be finalized, 
 * at which point the object may be discarded.
 * <p>
 * The <tt>finalize</tt> method is never invoked more than once by a Java
 * virtual machine for any given object.
 * <p>
 * Any exception thrown by the <code>finalize</code> method causes 
 * the finalization of this object to be halted, but is otherwise 
 * ignored. 
 *
 * @throws Throwable the <code>Exception</code> raised by this method
 */
protected void finalize() throws Throwable { }

【讨论】:

  • 这个想法看起来不错。对于我的问题,它不起作用,因为我假设问题来自外部库,我无法覆盖 finalize 方法。不过谢谢你的回答!
  • @Michael 在这种情况下,您必须按照其他人的建议使用一些分析器。
【解决方案3】:

不是垃圾回收的对象难道不是更有趣吗?

Anway,像VisualVM 这样的内存分析器是您真正需要的。它可以准确地显示您的应用程序中存在每个类的对象数量,还可以通过比较 GC 前后的堆转储来识别垃圾收集的类和对象县。

【讨论】:

    【解决方案4】:

    我建议您使用任何 java 分析器,如 JProfiler、Yourkit 等。 很容易看到垃圾回收的对象数量以及对象的类型。

    【讨论】:

      【解决方案5】:

      垃圾回收线程以低优先级运行。所以这个线程没有轮到它来做清理任务。

      也不能保证垃圾收集线程会一直运行。在您的应用程序中,垃圾收集的低优先级线程没有机会在应用程序线程上执行。因此堆不会从未使用的对象中清除,因此由于堆大小有限,应用程序会变慢。

      您可以通过覆盖public void finalize() 方法来计算垃圾收集的对象数量。更多详情请查看javadoc

      我建议您使用一些 java 分析器来诊断内存问题。

      【讨论】:

      • 感谢您的回答。是否有可能以更高的优先级运行垃圾收集?问题是,我已经有一个大约 5GB 的堆空间,并且由于我创建了一个删除很多对象,因此垃圾收集对于该应用程序非常非常重要。
      • 您无法更改垃圾收集器的优先级。您所能做的就是尽可能在使用对象之后立即取消引用。也不要创建不必要的对象,并在需要时懒惰地创建(单例设计模式)。也可以使用工厂设计模式来控制和缓存对象的创建
      猜你喜欢
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2019-02-26
      相关资源
      最近更新 更多