Сборка мусора Java выполнена, но уведомление GC не получено - PullRequest
0 голосов
/ 23 января 2019

Я следовал нескольким примерам из разных источников и имею следующий фрагмент:

 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 marksweep и ps scavenge. Цикл while завершен (что я воспринимаю как знак выполнения GC) , но уведомление не вызывается.Не является уведомлением GC или любого другого типа.

Является ли проблема в том, что слушатель зарегистрирован неправильно или GC действительно не выполнялся?кажется, что слабый ref действительно пустой после цикла while.

Я использую openjdk 1.8.0_144.

Ответы [ 2 ]

0 голосов
/ 27 января 2019

На самом деле проблема заключалась в следующем: A) Как упомянул Холгер в комментарии, я получал только уведомления для GC, которые влияли на старое поколение, и B) Отладчик не останавливался на моей точке останова, хотя код был выполнен, так что даже еслиЯ не мог сказать, что-то на самом деле сделал что-то.

0 голосов
/ 23 января 2019

Это то, что System.gc () javadoc говорит

Вызов метода gc предполагает, что виртуальная машина Java расходует усилия по переработке неиспользуемых объектов, чтобы сделать память в настоящее время они доступны для быстрого повторного использования. Когда контроль возвращается от вызова метода, виртуальная машина Java сделала все возможное освободить пространство от всех выброшенных объектов.

Вызов сборщика мусора не означает, что мусор будет собираться сразу по вызову. Но, вызывая gc, вы можете только предложить JVM собрать мусор, но не можете принудительно его вызвать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...