it-roy-ru.com

Запускается получение 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 минут и еще не закончил. Есть идеи почему?
61
rayman

jmap vs. jmap -F, а также jstack vs. 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.

Минусы.

  • Инструмент должен запускаться тем же пользователем (euidegid), что и целевая JVM.
  • Может использоваться только на живой и здоровой JVM.
  • Не будет работать, если целевая JVM запущена с -XX:+DisableAttachMechanism.

jmap -F/jstack -F

При запуске с -F инструменты переключаются в специальный режим, в котором есть агент обслуживания HotSpot . В этом режиме целевой процесс заморожен; инструменты читают его память через средства отладки ОС, а именно ptrace в Linux.

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

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

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

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

_/Плюсы

  • Сотрудничество с целевой JVM не требуется. Может использоваться даже на зависшем процессе.
  • ptrace работает всякий раз, когда достаточно прав на уровне ОС. Например. root может выводить процессы всех других пользователей.

Минусы.

  • Очень медленно для больших куч.
  • Инструмент и целевой процесс должны быть из одной и той же версии JDK.
  • Безопасная точка не гарантируется, когда инструмент устанавливается в принудительном режиме. Хотя jmap пытается обработать все особые случаи, иногда может случиться, что целевая JVM не находится в согласованном состоянии.

Заметка

Существует более быстрый способ получения дампов кучи в принудительном режиме. Сначала создайте coredump с помощью gcore , затем запустите jmap над сгенерированным файлом ядра. Смотрите связанный вопрос .

124
apangin

Я только что обнаружил, что jmap (и, по-видимому, jvisualvm при его использовании для создания дампа кучи) обеспечивает, что пользователь, запускающий jmap, должен быть тем же пользователем, который запускает процесс, пытающийся быть выгруженным.

в моем случае jvm, для которого я хочу создать дамп кучи, запускается пользователем linux "jboss". поэтому, когда Sudo jmap -dump:file.bin <pid> сообщал «Невозможно открыть сокет:», я смог получить свой дамп кучи, используя:

Sudo -u jboss jmap -dump:file.bin <pid>
68
ben_wing

Если ваше приложение работает как сервис systemd. Вы должны открыть файл сервиса под именем /usr/lib/systemd/system/ и назвать его именем сервиса. Затем проверьте, является ли атрибут privateTmp истинным.

Если это правда, вы должны изменить его на false, а затем обновить сервис по команде следующим образом: systemctl daemon-reload systemctl restart [servicename] Если вы хотите запустить jmap/jcmd перед перезапуском, вы можете использовать скрипт execStop в файле сервиса. Просто введите в него команду и выполните systemctl stop [service name]

0
Simple

Так же, как 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.

0
Lucas Basquerotto