Запуск jmap з неможливістю відкрити файл сокета


85

Мені довелося запустити 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 хвилин і ще не закінчив. Будь-які ідеї чому?

Відповіді:


181

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та egidJVM-процесу. Ось чому jmapне буде працювати, якщо запускається іншим користувачем (навіть коренем).

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

  6. Ця команда читається і виконується AttachListenerпотоком JVM. Весь вихід відправляється назад у сокет. Оскільки дамп купи робиться в процесі безпосередньо JVM, операція дійсно швидка. Однак JVM може робити це лише в безпечних точках . Якщо безпечної точки досягти не вдається (наприклад, процес зависає, не відповідає, або триває тривалий GC), час jmapочікування та не вдасться.

Давайте підсумуємо переваги та недоліки Dynamic Attach.

Плюси

  • Дамп купи та інші операції виконуються спільно JVM на максимальній швидкості.
  • Ви можете використовувати будь-яку версію jmapабо jstackдля підключення до будь-якої іншої версії JVM.

Мінуси

  • Інструмент повинен запускати той самий користувач ( euid/ egid), що і цільовий JVM.
  • Може використовуватися лише на живих та здорових JVM.
  • Не буде працювати, якщо цільову JVM запущено -XX:+DisableAttachMechanism.

jmap -F / jstack -F

Під час запуску з -Fінструментами переключіться на спеціальний режим, який має HotSpot Serviceability Agent . У цьому режимі цільовий процес заморожений; інструменти зчитують його пам'ять через засоби налагодження ОС, а саме 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створений основний файл. Дивіться відповідне запитання .


84

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

у моєму випадку jvm, для якого я хочу дамп купи, запускається користувачем Linux "jboss". отже, де sudo jmap -dump:file.bin <pid>повідомлялося "Неможливо відкрити сокет:", я зміг схопити дамп купи за допомогою:

sudo -u jboss jmap -dump:file.bin <pid>

Я думаю, що це має бути \ -dump: file.bin <pid>, оскільки вам потрібно уникнути - при передачі параметра з sudo у jmap.
Адам

Це воно! Вам також потрібно sudo для jmap та jcmd.
xtian

вау .. Це насправді спрацювало. Це має бути прийнятою відповіддю
Lalit Rao

3

Так само, як сказав 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теж.


Подвійне sudoрятує мій день!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 помилка поворотів sudo: jmap: command not found. Я вже налаштував шлях Java у .bash_profile, що мені робити.
роумер

@roamer Можливо, це тому, що коли ви працюєте як esкористувач, .bash_profileце не застосовується (оскільки профіль bash, як я припускаю, пов'язаний з вашим користувачем). Я раджу включити шлях Java у більш глобальний спосіб, або, можливо, вказати шлях Java у команді, наприклад sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283(де /java/pathзнаходиться шлях Java і переконайтеся, що він jmapу ньому є ).
Лукас Баскеротто,

Я налаштовую шлях Java у /home/es/.bash_profile, і я можу використовувати jmap при вході з користувачем es. Цей cmd sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283працює. Дуже дякую.
роумер

2

Якщо ваша програма працює як системна послуга, вам слід відкрити файл служби, який під /usr/lib/systemd/system/іменем вашої служби і названий. Потім перевірте, чи атрибут privateTmp відповідає дійсності.

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


Перш ніж я оновив /usr/lib/systemd/system/elasticsearch.service, встановивши для privateTmp значення false, я отримав таку помилку: Неможливо відкрити файл сокета: цільовий процес не відповідає або HotSpot VM не завантажений - хоча я працював як jmap як користувач еластичного пошуку
imdibiji
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.