Сборка мусора частного вызова метода - PullRequest
3 голосов
/ 16 февраля 2012

У меня проблема с использованием памяти в моем java-приложении, и я не могу понять, почему сборщик мусора не решает эту проблему.Код выглядит следующим образом:

public void foo() {
    for(int i=0; i<50000; i++) {
        bar(i);
    }
}

private void bar(int i) {
    LargeObject o = new LargeObject();
    ...
    dao.save(o);
}

Моя проблема в том, что экземпляры LargeObject не собирают мусор - чтобы определить это, я профилировал с помощью jprofiler и посмотрел на кучу.На экземпляры LargeObject никогда не ссылаются переменные класса, фактически они нигде не упоминаются за пределами bar().Я цепляюсь за соломинку, которую чувствую, но может ли это быть связано с тем, где транзакции начинаются / заканчиваются?Я попытался изменить bar() на public и аннотировать с помощью Propogation.REQUIRES_NEW, а также изменить аннотацию на foo() на Propogation.NEVER безрезультатно.

Код внутри дао выглядит следующим образом:

public void save(LargeObject o) {
    hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o);
}

Сборка мусора определенно запускается, поскольку я вижу ее активность в jprofiler.foo() занимает около 30 минут, bar() - 36 мс, пики сбора мусора примерно каждые 60 секунд.

Чтобы ответить на вопрос, почему я точно знаю, что они не занимаются сборкой мусора - ничего в системе не ссылается на LargeObject, но я вижу, как их экземпляры в куче увеличиваются при выполнении foo().

Ответы [ 2 ]

4 голосов
/ 16 февраля 2012

Очевидно, на них ссылается ваш провайдер JPA (или что-то скрывающееся за dao.save()).Вы позволяете ссылке снаружи, следовательно, ваш контроль над ней теряется.Независимо от того, делаете ли вы это в частном / публичном методе, не имеет значения.

Возможно, вы захотите поделиться дополнительной информацией об этом "DAO".

2 голосов
/ 16 февраля 2012

Я бы добавил к ответу @ MaDa, что цикл может вызвать нагрузку на уникальный сеанс, который должен был кэшировать все экземпляры Large Objects. Вам следует рассмотреть либо: сброс сеанса после сохранения, либо использование нового сеанса, либо очищенный сеанс для каждого LargeObject, если они не связаны

Чтение раздела Пакетная обработка может помочь вам понять вашу проблему

...