首页 > 解决方案 > 执行Java垃圾回收,但没有收到GC通知

问题描述

我遵循了来自各种来源的一些示例,并具有以下代码段:

 private void registerForMemUsageChanges() {
    List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
    for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMXBeans) {
        listenForGarbageCollectionOn(garbageCollectorMXBean); 
    }

}

private void listenForGarbageCollectionOn(GarbageCollectorMXBean garbageCollectorMXBean) {
    NotificationEmitter notificationEmitter = (NotificationEmitter) garbageCollectorMXBean;
    GarbageListener listener = new GarbageListener();
    notificationEmitter.addNotificationListener(listener, null, null);
}

public class GarbageListener implements NotificationListener {

    @Override
    public void handleNotification(Notification notification, Object handback) {
        if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
            doSomthing();//irrelevant
        }

    }
}

我添加了一个执行以下操作的测试(同样,基于我找到的示例),它似乎有效:

private void triggerGc() throws InterruptedException {
    Object obj = new Object();
    WeakReference ref = new WeakReference<Object>(obj);
    obj = null;
    while(ref.get() != null) {
        System.gc();
    }
}

在调试模式下运行时,我看到侦听器已注册到 ps markweep 和 ps scavenge。while 循环完成(我认为这是执行 GC 的标志),但没有调用任何通知。不是 GC 通知或任何类型。

是监听器注册错误还是没有真正执行GC的问题?在 while 循环之后,弱 ref 似乎确实是空的。

我正在使用 openjdk 1.8.0_144。

标签: javamemory-managementgarbage-collectionjavabeansjmx

解决方案


问题实际上是:A)正如 Holger 在评论中提到的,我只收到影响老一代的 GC 通知,并且 B)调试器没有在我的断点处停止,尽管代码已执行,所以即使我不能不知道,doSomething 确实做了一些事情。


推荐阅读