Тонкая разница в создании объекта приводит к радикально различному времени жизни объекта? - PullRequest
4 голосов
/ 14 июня 2011

Я запускаю приложение на Glassfish с Sun JVM.Один из наших разработчиков внес безобидное изменение, которое, похоже, нанесло ущерб системе.Все, что он сделал, это обернул существующий вызов метода фабрики другим, чтобы обеспечить некоторую регистрацию, например так:

// Old code
PreparedStatement stmt = connection.prepareStatement(sql);


// New code
PreparedStatement stmt = StatementLogger.prepareStatement(connection, sql);    

class StatementLogger {
    static PreparedStatement prepareStatement(Connection connection, String sql) {
        logger.info("Preparing SQL: " + sql);
        return connection.prepareStatement(sql);
    }
}

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

Конечно, живая ссылка на оператор сохраняется в новой версии намного дольше.Это может дать ему немного больше шансов выжить при незначительной сборке мусора.Но разница кажется мне тривиальной.(Один кадр всплывает.) Есть ли что-то еще в сборке мусора, которая могла бы позволить идентифицировать оператор как недолговечный объект в первом случае, но идентифицировал бы его как долгоживущий во втором случае?

Что здесь может происходить?

1 Ответ

0 голосов
/ 20 августа 2013

Единственное влияние на сборку мусора этого изменения заключается в том, что создается много новых строк, а затем собирается мусор.

когда вы говорите, что у вас закончились соединения с базой данных, это не имеет ничего общего с объектами, обрабатываемыми GC. Вы все еще можете иметь утечку объектов Соединения, но не исчерпать соединения БД. Вы говорите, что закрыли связь? Тогда у тебя не кончится.

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

...