План статьи:
1. Мотивация
2. Развлекательная часть (можно пропустить):
2.1. Теоретическая ситуация
2.2. Теоретическая проблема
2.3. Теоретическое решение
3. Основная часть:
3.1. Диаграммы
3.2. Заключение
Мотивация
В интернете огромное количество статей и диаграмм на эту тему, однако, по моему мнению, ни одна из них не позволяет сформировать общее представление об использовании памяти приложения на основе JVM, работающего в Docker контейнере. А без общего представления довольно сложно находить решения конкретных проблем в сложных системах. В результате, я решил выложить свои диаграммы. Уверен, они могут быть полезны в целях устранения пробелов в знаниях, в качестве отправной точки для изучения материала глубже и в помощь для решения конкретных задач и проблем на проекте.
Развлекательная часть (Можно пропустить)
Ситуация
Вы ведете разработку ПО, к примеру, для автоматизированного управления плантацией картофеля на планете Марс. ПО должно работать на легких, энерго эффективных портативных устройствах, типа Raspberry Pi. Также данное ПО не должно выходить за рамки выделенных ресурсов, так как на одном устройстве запущены иные ресурсоёмкие процессы. (Все требования перечислять не буду)... В результате изучения различных вариантов и проведения сравнительных испытаний, Вы приняли решение начать разработку ПО, которое будет запускаться на JVM в Docker контейнерах, с установленными ограничениями на использование ресурсов системы.
Проблема
В процессе тестов производительности Вы столкнулись с ситуацией, когда Docker контейнер крашится и перезапускается по причине превышения установленных лимитов по потреблению памяти, несмотря на то что размер Java Heap остается в допустимых пределах.
Решение
Необходимо разобраться, что может быть причиной потребления памяти в данном Docker контейнере, помимо Java Heap, настроить мониторинг, найти и устранить данную причину. В этом нам помогут диаграммы указанные ниже.
(В данном теоретическом примере, причинами утечки памяти были неверно сконфигурирована embedded RocksDB, вызываемая через rocksdbjni и самописная библиотека на C++, которая вызывалась через JNI)
Основная часть
Диаграммы
Упрощенная диаграмма использования памяти JVM в Docker контейнере:
Детализированная диаграмма использования памяти JVM в Docker контейнере с некоторыми параметрами:
Заключение
Данные диаграммы не имеют цели дать полные знания, но они могут стать отправной точкой в изучении темы глубже, восполнении пробелов в знаниях, тюнингу JVM и поиску проблемы в текущей системе.
Конструктивная критика, предложения и замечания приветствуются.