Запускается получение jmap Невозможно открыть файл сокета
Я должен был бежать jmap
чтобы взять кучу дамп моего процесса. но jvm
вернулся:
Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
Так что я использовал -F
:
./jmap -F -dump:format=b,file=heap.bin 10330
Attaching to process ID 10331, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
Dumping heap to heap.bin ...
- С помощью
-F
все в порядке для взятия свалки кучи? - Я жду 20 минут и еще не закончил. Есть идеи почему?
5 ответов
jmap
против jmap -F
, так же как jstack
против jstack -F
использовать совершенно разные механизмы для общения с целевой JVM.
jmap / jstack
Когда бегать без -F
эти инструменты используют механизм динамического присоединения. Это работает следующим образом.
Перед подключением к процессу Java 1234,
jmap
создает файл.attach_pid1234
в рабочем каталоге целевого процесса или в/tmp
,затем
jmap
посылаетSIGQUIT
к целевому процессу. Когда JVM ловит сигнал и находит.attach_pid1234
, это начинаетсяAttachListener
нить.AttachListener
поток создает сокет домена UNIX/tmp/.java_pid1234
слушать команды от внешних инструментов.По соображениям безопасности, когда соединение (от
jmap
), JVM проверяет, что учетные данные равноправного узла сокета равныeuid
а такжеegid
процесса JVM. Вот почемуjmap
не будет работать, если запущен другим пользователем (даже root).jmap
подключается к сокету и отправляетdumpheap
команда.Эта команда читается и выполняется
AttachListener
нить из JVM. Весь вывод отправляется обратно в сокет. Поскольку дамп кучи выполняется непосредственно JVM, операция выполняется очень быстро. Однако JVM может делать это только в безопасных точках. Если безопасная точка не может быть достигнута (например, процесс завис, не отвечает или выполняется длительный сборщик мусора),jmap
будет время ожидания и сбой.
Давайте суммируем преимущества и недостатки Dynamic Attach.
Плюсы.
- Дамп кучи и другие операции выполняются совместно JVM на максимальной скорости.
- Вы можете использовать любую версию
jmap
или жеjstack
подключиться к любой другой версии JVM.
Cons.
- Инструмент должен запускаться одним и тем же пользователем (
euid
/egid
) в качестве целевой JVM. - Может использоваться только на живой и здоровой JVM.
- Не будет работать, если целевая JVM запущена с
-XX:+DisableAttachMechanism
,
jmap -F / jstack -F
Когда бегать с -F
инструменты переключаются в специальный режим, в котором работает HotSpot Serviceability Agent. В этом режиме целевой процесс заморожен; инструменты читают его память через средства отладки ОС, а именно: ptrace
в линуксе
jmap -F
ЗапускаетPTRACE_ATTACH
на целевой JVM. Целевой процесс безоговорочно приостанавливается в ответ наSIGSTOP
сигнал.Инструмент читает память JVM, используя
PTRACE_PEEKDATA
,ptrace
может читать только одно слово за раз, поэтому слишком много вызовов требуется для чтения большой кучи целевого процесса. Это очень и очень медленно.Инструмент восстанавливает внутренние структуры JVM, основываясь на знании конкретной версии JVM. Поскольку разные версии JVM имеют разную структуру памяти,
-F
режим работает только еслиjmap
приходит из того же JDK, что и целевой Java-процесс.Инструмент сам создает дамп кучи, а затем возобновляет целевой процесс.
Плюсы.
- Сотрудничество с целевой JVM не требуется. Может использоваться даже на зависшем процессе.
ptrace
работает, когда достаточно прав на уровне ОС. Напримерroot
может сбрасывать процессы всех других пользователей.
Cons.
- Очень медленно для больших куч.
- Инструмент и целевой процесс должны быть из одной и той же версии JDK.
- Безопасная точка не гарантируется, когда инструмент устанавливается в принудительном режиме. Хоть
jmap
пытается обработать все особые случаи, иногда может случиться так, что целевая JVM не находится в согласованном состоянии.
Заметка
Существует более быстрый способ получения дампов кучи в принудительном режиме. Сначала создайте coredump с gcore
затем беги jmap
поверх созданного файла ядра. Смотрите связанный вопрос.
Я только что обнаружил, что jmap (и, по-видимому, jvisualvm при его использовании для создания дампа кучи) обеспечивает, что пользователь, запускающий jmap, должен быть тем же пользователем, который запускает процесс, пытающийся быть выгруженным.
в моем случае jvm, для которого я хочу создать дамп кучи, запускается пользователем linux "jboss". так где sudo jmap -dump:file.bin <pid>
сообщал "Невозможно открыть сокет:", я смог получить свой дамп кучи, используя:
sudo -u jboss jmap -dump:file.bin <pid>
Если ваше приложение работает как сервис systemd. Вам следует открыть файл сервиса, который находится под /usr/lib/systemd/system/
и назван вашим именем службы. Затем проверьте, является ли атрибут privateTmp истинным.
Если это правда, вы должны изменить его на false, а затем обновить службу командой следующим образом:
systemctl daemon-reload
systemctl restart [servicename]
Если вы хотите запустить jmap/jcmd перед перезапуском, вы можете использовать сценарий execStop в служебном файле. Просто введите в него команду и выполнить systemctl stop [service name]
Как сказал ben_wing, вы можете запустить с:
sudo -u jboss-as jmap -dump:file.bin <pid>
(в моем случае пользователь jboss-as
, но ваш может быть jboss
или какой-то другой.)
Но этого было мало, потому что он попросил у меня пароль ([sudo] password for ec2-user:
), хотя я мог бежать sudo
не запрашивая у меня пароль с другими командами.
Я нашел решение здесь, и мне просто нужно было добавить еще sudo
первый:
sudo sudo -u jboss-as jmap -dump:file.bin <pid>
Работает с другими командами, такими как jcmd
а также jinfo
тоже.
Обычно это решается с помощью -f.
Я столкнулся с ситуацией, когда полный GC делал невозможным выполнение команды.