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