2012-07-21

Дело о пропавшей памяти

Начали тестировать наш продукт, и система мониторинга на железке, оставленной на выходные неизменно рапортовала об отсутствии памяти. Причем график потребления памяти подозрительно линейно рос даже на простаивающей системе. И если на девелоперской среде можно было списать на отладочный режим, то на продакшене ничего подобного не было.

Сначала подключили родной профайлер, но без NetBeans он ничего интересного не показывал. Пришлось подключать тяжелую артиллерию в лице JProfier. Поковырявшись в огромной куче разных метрик нашли хотспоты в памяти. Подозрение пало на ту самую систему мониторинга. После рассматривания исходников выяснилось, что гибернейтовский EntityManager перзистил в базу собранные показатели жизнедеятельности системы и после этого не очищался. Контекст за день распухал на десятки тысяч объектов, которые были недосягаемы для мусорщика. Принцип неопределенности мониторинга: неправильно написанный мониторинг успешно убивает наблюдаемую систему.

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