1

如何在 NetbBeans 的 Java GC 周期中看到正在清除的对象?还有一种方法可以知道我在运行我的应用程序时何时触发了 GC?

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

4

3 回答 3

2

您可以通过使其可终结来跟踪对象。通常这是一个坏主意,但这是最简单的方法。

您可以通过查看 JMX 的 MemoryManagerMXBean(s) 来检测是否发生了 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 的开销。

于 2013-11-03T20:58:50.140 回答
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
于 2013-11-03T21:19:48.633 回答
0

基本上,没有。您可以声明一个终结器以了解它们是否不再可访问,但这并不意味着它们实际上已被处置。他们可能会在未来的某个时间被释放,或者根本不会被释放。

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

于 2013-11-03T21:04:16.227 回答