Java GC - 有一种方法可以确定收集哪些对象

时间:2010-04-13 11:40:47

标签: java garbage-collection

我正在尝试使用-verbosegc标志来监控应用中的gc活动。我可以看到有完整和次要的集合,但有没有办法确定(确定事件/ vm标志/其他什么)实际收集的对象?

谢谢!

7 个答案:

答案 0 :(得分:5)

有关内存中对象的一般信息,我建议您查看jvisualvm(它位于JDK的bin文件夹中)。它有很多关于VM在程序运行时正在做什么的有用信息,包括有关各种对象和内存状态的信息。

如果您想要更具体的内容,可以使用WeakReferences和ReferenceQueues。如果您只对几种类型的对象感兴趣,则此选项可能是可行的。您可以使用公共ReferenceQueue创建对象的WeakReference,然后让另一个线程定期检查Queue(请注意,队列只表示对象可以访问,而不是实际收集它们):

static ReferenceQueue<MyObject> MY_QUEUE = new ReferenceQueue<MyObject>();
static class MyReference extends WeakReference<MyObject>{
  public final String name;
  public MyReference(MyObject o, ReferenceQueue<MyObject> q){
    super(o, q);
    name = o.toString();
  }
}

static{
  Thread t = new Thread(){
    public void run(){
      while(true){
        MyReference r = (MyReference)MY_QUEUE.remove();
        System.out.println(r.name+" eligible for collection");
      }
    }
  }
  t.setDaemon(true);
  t.start();
}

public MyObject(){
  //normal init...
  new MyReference(this, MY_QUEUE);
}

答案 1 :(得分:3)

我自己没有使用过这个标志-XX:-TraceClassUnloading。它意味着跟踪类的卸载。

答案 2 :(得分:2)

在GC收集对象之前调用Object类的

finalize方法。在类中重写方法,如下所示:

@Override
protected void finalize() throws Throwable {
    System.out.println(this+" collected");
    super.finalize();
}

请注意,您只能使用此方法监控自己的类。因此,由于String是最终类,因此无法以这种方式监视String对象。

答案 3 :(得分:0)

我知道这不是你想要解决问题的方式,但无论如何它可能都有用。

您可以通过覆盖finalize方法在自己的对象上捕获事件。它不能100%保证对象将是垃圾收集,因为它可以创建对自身的引用,但它是一个开始。

看看this article这是一个非常好的GC教程。

答案 4 :(得分:0)

我不完全确定你为什么需要知道这一点。大多数人都想知道这一点,以确定他们是否有内存泄漏。 (在java中,这意味着通过保持对对象的引用来保持对象的活动)。

Netbeans有很好的工具来查看任何java应用程序的内存使用情况(也就是那些没有从netbeans运行的应用程序!)它们可以告诉你已经收集了多少对象以及你的内存使用情况,以及更多有用的统计数据。

答案 5 :(得分:0)

要分析内存问题,您需要检查哪些对象 GCed,而不是检查哪些对象得到了GC。

要检查哪些对象是GCed,您可以随时使用任何分析器,如Jprofiler等。

答案 6 :(得分:0)

通常,您无法确定回收哪个对象。但是你可以找到它的一个子集,但你必须使用Weak,Soft和Phantom引用来引用它们。通常,您要做的是创建一个对象,然后使用其中一个引用来引用它。请参阅this文章。