2013-11-03 30 views
1

如何在NetbBeans的Java GC周期中查看清除的对象? 当我运行我的应用程序时,还有一种方法可以知道GC何时被触发?如何跟踪NetBeans中由JAVA GC清除的对象?

非常感谢您的回复和时间。

+0

欢迎StackOverflow上。第一个问题+1。值得澄清你为什么想要这样做。 –

回答

2

您可以通过使对象成为可以确认来追踪对象。通常这是一个坏主意,但这是最简单的方法。

您可以通过查看JMX的MemoryManagerMXBean来检测GC是否已经发生。

NotificationFilter filter = new NotificationFilter() { 
    @Override 
    public boolean isNotificationEnabled(Notification notification) { 
     return true; 
    } 
}; 
NotificationListener listener = new 
     NotificationListener() { 
      @Override 
      public void handleNotification(Notification notification, Object handback) { 
       System.out.println(notification); 
      } 
     }; 
for (MemoryManagerMXBean memoryManagerMXBean : ManagementFactory.getMemoryManagerMXBeans()) { 
    if (memoryManagerMXBean instanceof NotificationBroadcaster) 
     ((NotificationBroadcaster) memoryManagerMXBean).addNotificationListener(listener, filter, memoryManagerMXBean); 
} 
System.gc(); 
Thread.sleep(500); 

打印

javax.management.Notification[source=java.lang:type=GarbageCollector,name=PS Scavenge][type=com.sun.management.gc.notification][message=PS Scavenge] 
javax.management.Notification[source=java.lang:type=GarbageCollector,name=PS MarkSweep][type=com.sun.management.gc.notification][message=PS MarkSweep] 

很显然,你不会做任何的这些东西,除非你有一个很好的理由,这是非常有用的,因为它们增加了复杂到您的代码,并在你的JVM的开销。

0

基本上没有。 你可以声明一个终结器来知道它们是否不再可用,但这并不意味着它们已经被处置。他们可能在将来有一段时间被释放,或者根本没有被释放。

如果您怀疑应用程序中存在内存泄漏,则有专门用于此类分析的工具,您可以要求Java VM打印详细的GC信息(-XX:-PrintGCDetails)。 有关它的更多信息,请参阅http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

1

您可以使用PhantomReference - 它是一种如何跟踪对象资格被收回的不定型的性能损失。另外,不可能将幻像可到达的物体意外移回。

您可以使用类似下面的代码来实现这一目标:

public class GCTracker extends PhantomReference { 
    private Object id; 
    public GCTracker(Object object, ReferenceQueue referenceQueue, Object id) { 
    super(object, referenceQueue); 
    this.id = id; 
    } 
    public Object getId() { 
    return id; 
    } 
} 
ReferenceQueue<GCTracker> q = new ReferenceQueue<>(); 
Object id = "id1"; 
// never use the same object for the referent and the id 
GCTracker pr = new GCTracker(object, referenceQueue, id); 
// Later on another point 
GCTracker r = q.remove(); 

// Use r.getId() to track the object being reclaimed