Ausführen von jmap Getting Socket-Datei kann nicht geöffnet werden

85

Ich musste laufen jmap, um einen Heap-Dump meines Prozesses zu erstellen. aber jvmzurückgegeben:

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

Also habe ich verwendet -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. Verwenden -F ist in Ordnung für Heap Dump?
  2. Ich warte 20 Minuten und bin noch nicht fertig. Irgendwelche Ideen warum?
Rayman
quelle

Antworten:

180

jmapvs. jmap -Fsowie jstackvs. jstack -Fverwenden völlig unterschiedliche Mechanismen, um mit der Ziel-JVM zu kommunizieren.

jmap / jstack

Wenn Sie ohne -Fdiese Tools ausgeführt werden, verwenden Sie den Dynamic Attach Mechanism . Dies funktioniert wie folgt.

  1. Erstellen Sie vor dem Herstellen jmapeiner Verbindung zum Java-Prozess 1234 eine Datei .attach_pid1234im Arbeitsverzeichnis des Zielprozesses oder unter /tmp.

  2. Dann jmapsendet SIGQUITan den Zielprozess. Wenn JVM das Signal fängt und findet .attach_pid1234, startet es den AttachListenerThread.

  3. AttachListenerThread erstellt einen UNIX-Domänensocket /tmp/.java_pid1234, um Befehle von externen Tools abzuhören.

  4. Aus Gründen der Sicherheit , wenn eine Verbindung (ab jmap) akzeptiert wird , überprüft , dass JVM Berechtigungsnachweise des Sockels Peer gleich euidund egidder JVM - Prozess. Aus diesem Grund jmapfunktioniert es nicht, wenn es von einem anderen Benutzer (auch von root) ausgeführt wird.

  5. jmapstellt eine Verbindung zum Socket her und sendet einen dumpheapBefehl.

  6. Dieser Befehl wird vom AttachListenerThread der JVM gelesen und ausgeführt . Alle Ausgaben werden an den Socket zurückgesendet. Da der Heap-Dump direkt von JVM in Bearbeitung ist, ist der Vorgang sehr schnell. JVM kann dies jedoch nur an Sicherheitspunkten tun . Wenn ein Sicherheitspunkt nicht erreicht werden kann (z. B. der Prozess hängt, reagiert nicht oder ein langer GC läuft), tritt jmapeine Zeitüberschreitung auf und schlägt fehl.

Lassen Sie uns die Vor- und Nachteile von Dynamic Attach zusammenfassen.

Vorteile.

  • Heap-Dump und andere Vorgänge werden von JVM gemeinsam mit maximaler Geschwindigkeit ausgeführt.
  • Sie können eine beliebige Version von jmapoder verwenden jstack, um eine Verbindung zu einer anderen Version von JVM herzustellen.

Nachteile

  • Das Tool sollte von demselben Benutzer ( euid/ egid) wie die Ziel-JVM ausgeführt werden.
  • Kann nur für lebende und gesunde JVM verwendet werden.
  • Funktioniert nicht, wenn die Ziel-JVM gestartet wird -XX:+DisableAttachMechanism.

jmap -F / jstack -F

Wenn Sie mit -Fden Tools ausgeführt werden, wechseln Sie in den Spezialmodus mit HotSpot Serviceability Agent . In diesem Modus wird der Zielprozess eingefroren. Die Tools lesen ihren Speicher über Betriebssystem-Debugging-Funktionen, nämlich ptraceunter Linux.

  1. jmap -Fruft PTRACE_ATTACHauf der Ziel-JVM auf. Der Zielprozess wird als Reaktion auf das SIGSTOPSignal bedingungslos angehalten .

  2. Das Tool liest den JVM-Speicher mit PTRACE_PEEKDATA. ptraceEs kann jeweils nur ein Wort gelesen werden, sodass zu viele Aufrufe erforderlich sind, um den großen Heap des Zielprozesses zu lesen. Das ist sehr und sehr langsam.

  3. Das Tool rekonstruiert interne JVM-Strukturen basierend auf dem Wissen der jeweiligen JVM-Version. Da verschiedene Versionen von JVM unterschiedliche Speicherlayouts haben, -Ffunktioniert der Modus nur, wenn er jmapvom selben JDK stammt wie der Java-Zielprozess.

  4. Das Tool erstellt selbst einen Heap-Dump und setzt dann den Zielprozess fort.

Vorteile.

  • Es ist keine Mitarbeit der Ziel-JVM erforderlich. Kann auch bei aufgehängtem Prozess verwendet werden.
  • ptracefunktioniert immer dann, wenn Berechtigungen auf Betriebssystemebene ausreichen. Zum Beispiel rootkönnen die Prozesse aller anderen Benutzer auszugeben .

Nachteile

  • Sehr langsam für große Haufen.
  • Das Tool und der Zielprozess sollten aus derselben Version von JDK stammen.
  • Der Sicherheitspunkt ist nicht garantiert, wenn das Werkzeug im Zwangsmodus angebracht wird. Obwohl jmapversucht wird, alle Sonderfälle zu behandeln, kann es manchmal vorkommen, dass sich die Ziel-JVM nicht in einem konsistenten Zustand befindet.

Hinweis

Es gibt eine schnellere Möglichkeit, Heap-Dumps im erzwungenen Modus zu erstellen. Erstellen Sie zuerst einen Coredump mit gcoreund führen Sie dann jmapdie generierte Kerndatei aus. Siehe die zugehörige Frage .

Apangin
quelle
84

Ich habe gerade festgestellt, dass jmap (und vermutlich jvisualvm, wenn es zum Generieren eines Heap-Dumps verwendet wird) erzwingt, dass der Benutzer, der jmap ausführt, derselbe Benutzer sein muss, der den Prozess ausführt, der versucht, einen Dump auszuführen.

In meinem Fall wird die JVM, für die ich einen Heap-Dump haben möchte, vom Linux-Benutzer "jboss" ausgeführt. Wo also sudo jmap -dump:file.bin <pid>"Socket konnte nicht geöffnet werden:" gemeldet wurde, konnte ich meinen Heap-Dump mit folgenden Daten abrufen:

sudo -u jboss jmap -dump:file.bin <pid>
ben_wing
quelle
Ich denke, es sollte \ -dump: file.bin <pid> sein, da Sie dem - entkommen müssen, wenn Sie den Parameter von sudo in jmap übergeben.
Adam
Das ist es! Sie müssen auch für jmap und jcmd sudo.
Xtian
wow .. Das hat tatsächlich funktioniert. Dies sollte die akzeptierte Antwort sein
Lalit Rao
3

Genau wie ben_wing sagte, können Sie laufen mit:

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

(In meinem Fall ist der Benutzer jboss-as, aber Ihr könnte jbossoder ein anderer sein.)

Aber es war nicht genug, weil es mich nach einem Passwort fragte ( [sudo] password for ec2-user:), obwohl ich laufen konnte, sudoohne mich mit anderen Befehlen zur Eingabe eines Passworts aufzufordern.

Ich habe hier die Lösung gefunden und musste erst eine hinzufügen sudo:

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

Es funktioniert mit anderen Befehlen wie jcmdund jinfoauch.

Lucas Basquerotto
quelle
Double sudorettet meinen Tag!
Sher10ck
[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 dreht Fehler sudo: jmap: command not found. Ich habe bereits Java-Pfad in .bash_profile konfiguriert, was soll ich tun.
Roamer
@roamer Vielleicht liegt es daran, dass wenn Sie als esBenutzer ausgeführt werden, das .bash_profilenicht angewendet wird (weil das Bash-Profil mit Ihrem Benutzer zusammenhängt, nehme ich an). Ich rate den Java - Pfad in einer globaleren Art und Weise aufzunehmen, oder vielleicht den Java - Pfad in dem Befehl angeben, wie sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283(wo /java/pathder Java - Pfad ist, und stellen Sie sicher , dass es jmapdarin ).
Lucas Basquerotto
Ich konfiguriere den Java-Pfad in /home/es/.bash_profile und kann jmap verwenden, wenn ich mich mit dem Benutzer anmelde. Dieser cmd sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283funktioniert. Danke vielmals.
Roamer
2

Wenn Ihre Anwendung als systemd-Dienst ausgeführt wird. Sie sollten die Dienstdatei öffnen, die unter Ihrem Dienstnamen steht /usr/lib/systemd/system/und nach diesem benannt ist. Überprüfen Sie dann, ob das Attribut privateTmp wahr ist.

Wenn dies der Fall ist, sollten Sie es in false ändern und den Dienst dann wie folgt mit dem Befehl systemctl daemon-reload systemctl restart [servicename] aktualisieren : Wenn Sie jmap / jcmd vor dem Neustart ausführen möchten, können Sie das execStop-Skript in der Dienstdatei verwenden. Geben Sie einfach den Befehl ein und führen Sie ihn aussystemctl stop [service name]

Einfach
quelle
Bevor ich die Datei /usr/lib/systemd/system/elasticsearch.service aktualisiert und privateTmp auf false gesetzt habe, wurde folgende Fehlermeldung angezeigt: Socket-Datei kann nicht geöffnet werden: Zielprozess reagiert nicht oder HotSpot-VM wurde nicht geladen - obwohl ich jmap as ausgeführt habe der elasticsearch user
imdibiji