Запускается получение 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 ...
  1. С помощью -F все в порядке для взятия свалки кучи?
  2. Я жду 20 минут и еще не закончил. Есть идеи почему?

5 ответов

Решение

jmap против jmap -F, так же как jstack против jstack -F использовать совершенно разные механизмы для общения с целевой JVM.

jmap / jstack

Когда бегать без -F эти инструменты используют механизм динамического присоединения. Это работает следующим образом.

  1. Перед подключением к процессу Java 1234, jmap создает файл .attach_pid1234 в рабочем каталоге целевого процесса или в /tmp,

  2. затем jmap посылает SIGQUIT к целевому процессу. Когда JVM ловит сигнал и находит .attach_pid1234, это начинается AttachListener нить.

  3. AttachListener поток создает сокет домена UNIX /tmp/.java_pid1234 слушать команды от внешних инструментов.

  4. По соображениям безопасности, когда соединение (от jmap), JVM проверяет, что учетные данные равноправного узла сокета равны euid а также egid процесса JVM. Вот почему jmap не будет работать, если запущен другим пользователем (даже root).

  5. jmap подключается к сокету и отправляет dumpheap команда.

  6. Эта команда читается и выполняется 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 в линуксе

  1. jmap -F Запускает PTRACE_ATTACH на целевой JVM. Целевой процесс безоговорочно приостанавливается в ответ на SIGSTOP сигнал.

  2. Инструмент читает память JVM, используя PTRACE_PEEKDATA, ptrace может читать только одно слово за раз, поэтому слишком много вызовов требуется для чтения большой кучи целевого процесса. Это очень и очень медленно.

  3. Инструмент восстанавливает внутренние структуры JVM, основываясь на знании конкретной версии JVM. Поскольку разные версии JVM имеют разную структуру памяти, -F режим работает только если jmap приходит из того же JDK, что и целевой Java-процесс.

  4. Инструмент сам создает дамп кучи, а затем возобновляет целевой процесс.

Плюсы.

  • Сотрудничество с целевой 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 делал невозможным выполнение команды.

Другие вопросы по тегам