Проверка карты памяти процесса
Собственное отслеживание памяти учитывает только структуры виртуальной машины Java, но не учитывает отображенные в памяти файлы и собственную память, выделенную общими библиотеками (включая собственный код библиотеки классов Java),Кроме того, NMT не отслеживает какую-либо внутреннюю фрагментацию malloc
- стандартного распределителя libc.
Во-первых, чтобы проанализировать использование Java-процесса вне кучи, рассмотрим его полную карту памяти:
pmap -X <pid>
Это позволит пролить свет на то, используется ли память сопоставленными файлами или анонимными областями.
Изменение стандартного распределителя
Если вы видите количество анонимных областей, кратное 64 МБ, это может быть признаком малокен арена.Известно, что libc malloc имеет проблемы с чрезмерным использованием виртуальной памяти в некоторых системах.Использование jemalloc
или tcmalloc
в качестве замены для замены (даже без функции профилирования) может стать решением в этом случае.
Собственные распределения профилей
К сожалению, профилировщик jemalloc ничего не знает о Java;график разбивается на последнюю нативную функцию, поэтому вывод может выглядеть запутанным.В вашем случае jemalloc предполагает, что проблема может быть связана с загрузкой классов и System.loadLibrary
, но трудно сказать это без полной картины.
Async-profiler позволяет отслеживать собственные распределенияв контексте Java.Выполнить
./profiler.sh -d <duration> -e malloc -f malloc.svg <pid>
Это приведет к появлению Графика пламени из malloc
вызовов, например:
Это всего лишь пример, демонстрирующий, как java.util.zip.GZIPOutputStream
может быть источником встроенной памяти.Конечно, ваш случай будет другим.
Обратите внимание , что malloc
сами вызовы не означают утечку памяти.Например, память может быть выделена, а затем освобождена вскоре после этого.График - это просто подсказка, где искать.
Чтобы найти места, где RSS увеличивается, вы можете отслеживать mprotect
или mmap
звонки.Это можно сделать с помощью async-profiler аналогичным образом:
./profiler.sh -d <duration> -e mprotect -f mprotect.svg <pid>
./profiler.sh -d <duration> -e mmap -f mmap.svg <pid>
Обратите внимание на библиотеки агентов
Я заметил функции cbClassPrepare
и classTrack_processUnloads
в вашем графе jemalloc.Это означает, что вы используете jdwp
агент отладки.Это определенно может быть причиной чрезмерного выделения памяти - раньше я видел утечки памяти в jdwp
.Любая другая библиотека агентов, включенная с помощью опций -agentlib
, -agentpath
или -javaagent
, также является подозрительной, поскольку ее собственное использование памяти не отслеживается JVM.