Сборка мусора, похоже, не работает в java

В приведенном ниже методе есть 2 цикла for. Первый цикл повторяется 36000 раз, а внутренний цикл forloop повторяется 24 раза, поэтому общее количество вставляемых записей будет 864000. Выполнение кода длится почти 3,5 часа и завершается. (Вставка записей не удалась). Закрытие сеанса и фиксация транзакции выполняются только после конца внешнего цикла for. Обнаружено, что потребление оперативной памяти составляет почти 6,9 ГБ во время выполнения.

@SuppressWarnings("unchecked")


public void createBRResults() {

    List<BusinessRules> businessRuleList = null;
    Organization organization = null;
    Brresults brresults = null;
    Criteria criteria = null;
    Criteria newCriteria = null;
    String brStatus = "Live";
    Date date = new Date();
    Session session = sessionFactory.openSession();
    Transaction transaction = null;
    try {
        if (callInfos == null) {
            callInfos = getEntities(CallInfo.class);
        }
        for (CallInfo callInfo : callInfos) {
            transaction = session.beginTransaction();
            criteria = session.createCriteria(BusinessRules.class);
            criteria.createCriteria("businessGoals").add(
                    Restrictions.eq("category", callInfo.getCategory()));
            businessRuleList = criteria.list();
            organization = callInfo.getOrganization();
            for (BusinessRules businessRule : businessRuleList) {
                brresults = new Brresults();
                brresults.setBusinessRule(businessRule);
                brresults.setCallInfo(callInfo);
                brresults.setCreatedDate(date);
                brresults.setModifiedDate(date);
                brresults.setOrganization(organization);
                brresults.setBrrStatus(brStatus);
                brresults.setBrrValue(Math.random() < 0.5 ? 0 : 1);
                session.save(brresults);
                brresults = null;
            }
            criteria = null;
            organization = null;
            businessRuleList = null;
            session.flush();
            session.clear();
            transaction.commit();
            System.gc();
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        session.close();
    }
}

Я прикрепил последние несколько строк журнала GC, чтобы указать выделение памяти.

17034.595: [Полный сборщик мусора (эргономика) [PSYoungGen: 979968K-> 979964K (1862144K)] [ParOldGen: 5576158K-> 5576158K (5576192K)] 6556126K-> 6556123K (7438336K), [Metaspace: 2310195K] (1071195K) (2310195K) (2310195K) 2,1041939 секунд] [Время: пользователь = 8,61, системный = 0,00, реальный = 2,11 секунды]

17036.699: [Полный сборщик мусора (эргономика) [PSYoungGen: 979968K-> 979964K (1862144K)] [ParOldGen: 5576158K-> 5576158K (5576192K)] 6556126K-> 6556123K (7438336K), [Metaspace: 2310195K] (10194195K) (2310195K) (2310195K) (2310195K) 1,5930338 секунд] [Times: user = 9,39 sys = 0,00, real = 1,59 секунды] 17038,292: [Полная сборка мусора (эргономика) [PSYoungGen: 979968K-> 979964K (1862144K)] [ParOldGen: 5576158K-> 5576158K (5576192K)] 65 > 6556122K (7438336K), [Metaspace: 23195K-> 23195K (1071104K)], 1,9376959 секунд] [Times: user = 8,51 sys = 0,00, real = 1,94 секунды]

17040.230: [Полный сборщик мусора (эргономика) [PSYoungGen: 979968K-> 830418K (1862144K)] [ParOldGen: 5576158K-> 5576027K (5576192K)] 6556126K-> 6406445K (7438336K), [Metaspace: 2310196K], [Metaspace> 2310196K] 2,9929302 секунды] [Время: пользователь = 17,97, системный = 0,00, реальный = 3,00 секунды]

Куча PSYoungGen всего 1862144K, использовано 889367K [0x0000000715d80000, 0x00000007bdc80000, 0x00000007c0000000)

Иден пространство 979968K, 90% использовали [0x0000000715d80000,0x000000074c205e48,0x0000000751a80000) из пространства 882176K, 0% использовали [0x0000000787f00000,0x0000000787f00000,0x00000007bdc80000) в пространстве 885760K, 0% использовали [0x0000000751a80000,0x0000000751a80000,0x0000000787b80000) ParOldGen всего 5576192K, используется 5576027K [0x00000005c1800000 , 0x0000000715d80000, 0x0000000715d80000) объектное пространство 5576192K, используется 99% [0x00000005c1800000,0x0000000715d56d38,0x0000000715d80000) Используемое метаспространство 23223K, емкость 23502K, зафиксировано 24064K, зарезервировано 1071104K, занято пространство классов 2437K57, зафиксировано 253743K

Но если я закрываю сеанс и открываюсь снова для каждых 24 итераций, вставка записей выполняется успешно, и время, необходимое для этого, составляет 55 минут. но использование ОЗУ составляет около 3 ГБ.

Почему сборка мусора не происходит должным образом? Какие ошибки в коде?


person Popeye    schedule 22.03.2016    source источник


Ответы (1)


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

person chrylis -cautiouslyoptimistic-    schedule 22.03.2016
comment
Вы говорите мне закрывать сеанс для каждой итерации. Если да, то это правильный способ пакетной вставки? - person Popeye; 22.03.2016
comment
@sriram Я предлагаю периодически закрывать его. Это может быть каждая итерация или какой-либо другой интервал, в зависимости от того, что делает ваш код более понятным. Вам просто нужно признать, что сеанс поддерживает надежный кеш, и учитывать это. - person chrylis -cautiouslyoptimistic-; 22.03.2016