Комментарии 22
Прежде всего, нужно запустить приложение со следующими флагами JVM:
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
Эти опции позволят запустить Flight Recorder – утилита, которая поможет собрать информацию об использовании памяти (и много другой важной информации) во время выполнения программы. Я не буду описывать здесь как запустить Flight Recorder, эта информация легко гуглится. В моем случае было достаточно запустить FR на 10-11 минут.
К этому всегда полезно добавлять дисклеймер, о том что эти фичи нельзя использовать в production-окружении не имея коммерческой лицензии на Oracle JDK. Для разработки/отладки JMC использовать можно спокойно.
Ещё полезная ссылка: http://blogs.atlassian.com/2013/03/so-you-want-your-jvms-heap/
Описано как снимать дапм памяти максимально быстро (в случае если надо снять дамп на проде и нужно минимизировать время простоя). Фактически, при таком способе, скорость создания дампа ограничена только скоростью дисковой подсистемы, что на нормальных серверах весьма приятно.
Результат спокойно открывается в современной версии MAT без предварительных преобразований. Главное чтобы версия JVM совпадала с версией с которой дамп снимался.
Только так удалось снять дамп с живого прода.
К стати, если делать дамп таким макаром, то там ещё и информация о потоках сохраняется, Это позволяет сразу переходить к списку потоков (большая жёлтая шестерёнка на скриншоте MAT) и смотреть какой поток сколько памяти удерживает и почему. Сокращает время поиска причины утечки памяти буквально до нескольких минут.
Буквально вот только что очередной дамп расковырял. Основное время ушло на перекачку дампа к себе на комп и его индексирование. Далее буквально за пару минут виноватого нашёл.
Как я говорил выше, для разработки (не в production) можно использовать JRF не имея коммерческой лицензии:
The Java Flight Recorder (JFR) is a commercial feature. You can use it for free on developer desktops/laptops, and for evaluation purposes in test, development, and production environments. However, to enable JFR on a production server, you require a commercial license. Using JMC UI for other purposes on the JDK does not require a commercial license.
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr002.html
Чтобы искать утечку памяти надо глубоко понимать программу, в которой утечки ищутся. Чтобы заметить странность. А как её видеть- объяснить сложно. Временами методика поиска напоминает анекдот про апельсин.
Если про EMT — то GC-root как-то лучше работает (в visualVM оно то ли не работает, то ли неработоспособно). Но памяти этот зверь кушает- очень хорошо.
PS: apangin вроде как делал своё семплирование, которое работает вне safe-point — но всё ссылку на утилитку не могу найти. Подскажите, кто помнит, пожалуйста :)
https://github.com/apangin/async-profiler
Кстати говоря, на предстоящем JPoint будем с коллегой подробно рассказывать как раз про методики семлирования, и к этому событию приурочу кое-какие интересные обновления в async-profiler… Следите за новостями :)
Плохая иллюстрация, мы просто не увидели full GC — который собрал бы мусор, случайно попадающий в old space. Соответственно на хорошей иллюстрации должно быть более одного цикла такого full gc для понимания его динамики.
И, кстати, зачем надо было частично(!) неодинаково(!) замазывать одинаковые(!) имена пакетов на скриншоте? они же легко мержатся и начинают читаться:
Диагностика утечек памяти в Java