代码之家  ›  专栏  ›  技术社区  ›  Seffi

JavaGC—有没有一种方法可以确定收集了哪些对象

  •  7
  • Seffi  · 技术社区  · 14 年前

    谢谢!

    7 回复  |  直到 14 年前
        1
  •  6
  •   M. Jessup    14 年前

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

    如果您想要更具体的东西,可以使用WeakReferences和ReferenceQueues。如果您只对少数类型的对象感兴趣,那么此选项可能是可行的。您可以在使用公共引用队列创建对象时创建对对象的WeakReference,然后让另一个线程定期检查队列(请注意,队列仅表示对象是可访问的,而不是实际收集的):

    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);
    }
    
        2
  •  3
  •   Eran    11 年前

    -XX:-TraceClassUnloading . 它是用来追踪类的卸载。

        3
  •  2
  •   Borislav Gizdov    9 年前

    就在GC收集对象之前调用对象类的finalize方法。重写类中的方法,如下所示:

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

    请注意,使用此方法只能监视自己的类。因此,由于String是最后一个类,因此不能用这种方法监视String对象。

        4
  •  0
  •   Allain Lalonde    14 年前

    我知道这不是你想解决问题的方法,但它可能还是有用的。

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

    this article 这是一个相当不错的GC教程。

        5
  •  0
  •   Thirler    14 年前

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

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

        6
  •  0
  •   Suraj Chandran    14 年前

    GCed,而不是检查哪些对象得到GCed。

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

        7
  •  0
  •   Chuk Lee    14 年前

    一般来说,您无法确定回收哪个对象。然而,你可以找到它的一个子集,但是你必须使用弱的、软的和虚的引用来引用它们。通常,您要做的是创建一个对象,然后使用其中一个引用引用它。看到了吗 this