Jmap çalıştırılıyor soket dosyası açılamıyor


88

Ben çalıştırmak zorunda jmapbenim sürecin yığın dökümü almak için. ancak jvmgeri döndü:

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

Ben de şunu kullandım -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 Yığın dökümü almak için kullanmak tamam mı?
  2. 20 dakika bekliyorum ve henüz bitirmedim. Herhangi bir fikriniz neden?

Yanıtlar:


187

jmapgenel jmap -Fyanı sıra, jstackgenel jstack -Fkullanımı tamamen farklı mekanizmalar hedef JVM ile communcate için.

jmap / jstack

-FBu araçlar olmadan çalıştırıldığında Dinamik Bağlantı Mekanizması kullanın . Bu aşağıdaki gibi çalışır.

  1. Java işlemi 1234'e bağlanmadan önce , hedef işlemin çalışma dizininde veya adresinde jmapbir dosya oluşturur ..attach_pid1234/tmp

  2. Ardından hedef işleme jmapgönderir SIGQUIT. JVM sinyali yakalayıp bulduğunda .attach_pid1234, AttachListeneriş parçacığı başlatır .

  3. AttachListenerthread /tmp/.java_pid1234harici araçlardan gelen komutları dinlemek için UNIX etki alanı soketi oluşturur .

  4. (Bir bağlantı Güvenlik nedenleriyle jmap) kabul edilir, JVM doğrular soket eş kimlik bilgileri ile eşit olduğunu euidve egidJVM sürecin. Bu nedenle jmap, farklı bir kullanıcı tarafından çalıştırılırsa (kök tarafından bile) çalışmayacaktır.

  5. jmapsokete bağlanır ve dumpheapkomut gönderir .

  6. Bu komut AttachListenerJVM'nin iş parçacığı tarafından okunur ve yürütülür . Tüm çıktı sokete geri gönderilir. Yığın dökümü doğrudan JVM tarafından süreç içinde yapıldığından, işlem gerçekten hızlıdır. Ancak, JVM sadece karşılığında yapabilecek safepoints . Bir kayıt noktasına ulaşılamazsa (örn. İşlem askıya alınmışsa, yanıt vermiyorsa veya uzun bir GC devam ediyorsa), jmapzaman aşımına uğrayacak ve başarısız olacaktır.

Dynamic Attach'ın avantajlarını ve dezavantajlarını özetleyelim.

Artıları.

  • Yığın dökümü ve diğer işlemler, maksimum hızda JVM tarafından ortaklaşa yürütülür.
  • JVM'nin herhangi bir sürümünü jmapveya jstackbaşka bir JVM sürümüne bağlanmak için kullanabilirsiniz .

Eksileri.

  • Araç , hedef JVM ile aynı kullanıcı ( euid/ egid) tarafından çalıştırılmalıdır .
  • Yalnızca canlı ve sağlıklı JVM'de kullanılabilir.
  • Hedef JVM ile başlatılırsa çalışmayacaktır -XX:+DisableAttachMechanism.

jmap -F / jstack -F

Araçlarla çalıştırıldığında, HotSpot Hizmet Verebilirlik Aracısı-F içeren özel moda geçin . Bu modda hedef süreç dondurulur; araçlar hafızasını işletim sistemi hata ayıklama olanakları aracılığıyla, yani Linux'ta okur .ptrace

  1. jmap -FPTRACE_ATTACHhedef JVM'yi çağırır . Hedef süreç, SIGSTOPsinyale yanıt olarak koşulsuz olarak askıya alınır .

  2. Araç, kullanarak JVM belleğini okur PTRACE_PEEKDATA. ptracebir seferde yalnızca bir kelimeyi okuyabilir, bu nedenle hedef sürecin büyük yığınını okumak için çok fazla çağrı gerekir. Bu çok ve çok yavaş.

  3. Araç, belirli JVM sürümünün bilgisine dayalı olarak JVM iç yapılarını yeniden oluşturur. JVM'nin farklı sürümleri farklı bellek düzenine sahip olduğundan, -Fmod yalnızca jmaphedef Java işlemiyle aynı JDK'dan geliyorsa çalışır .

  4. Araç, yığın dökümü oluşturur ve ardından hedef işlemi devam ettirir.

Artıları.

  • Hedef JVM'den herhangi bir işbirliği gerekli değildir. Asılı bir işlemde bile kullanılabilir.
  • ptraceişletim sistemi düzeyinde ayrıcalıklar yeterli olduğunda çalışır. Örneğin root, diğer tüm kullanıcıların işlemlerini dökebilir .

Eksileri.

  • Büyük yığınlar için çok yavaş.
  • Araç ve hedef işlem aynı JDK sürümünden olmalıdır.
  • Alet zorunlu modda takıldığında kayıt noktası garanti edilmez. Gerçi jmapdener tüm özel davalarına bakacak, bazen hedef JVM tutarlı bir durumda olmadığını ortaya çıkabilir.

Not

Zorunlu modda yığın dökümleri almanın daha hızlı bir yolu vardır. İlk olarak, bir çekirdek döküm oluşturun gcore, ardından jmapoluşturulan çekirdek dosya üzerinde çalıştırın . İlgili soruya bakın .


85

Jmap'in (ve muhtemelen jvisualvm'nin bir yığın dökümü oluşturmak için kullandığında) jmap'i çalıştıran kullanıcının, atılmaya çalışan işlemi çalıştıran aynı kullanıcı olmasını zorunlu kıldığını buldum.

benim durumumda bir yığın dökümü istediğim jvm linux kullanıcısı "jboss" tarafından çalıştırılıyor. sudo jmap -dump:file.bin <pid>"Soket açılamıyor:" nerede bildiriliyordu, aşağıdakileri kullanarak yığın dökümümü alabildim:

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

Parametreyi sudo'dan jmap'e geçirirken - 'den kaçmanız gerektiği için \ -dump: file.bin <pid> olması gerektiğini düşünüyorum.
adam

Budur! Ayrıca jmap ve jcmd için sudo yapmanız gerekir.
xtian

vay .. Bu gerçekten işe yaradı. Kabul edilen cevap bu olmalı
Lalit Rao

3

Ben_wing'in dediği gibi , aşağıdakilerle koşabilirsiniz:

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

(benim durumumda kullanıcı öyle jboss-as, ancak sizinki jbossveya başka biri olabilir.)

Ancak bu yeterli değildi, çünkü benden bir şifre ( [sudo] password for ec2-user:) istedi , ancak sudodiğer komutlarla bir şifre sormadan da çalıştırabilirdim .

Çözümü burada buldum ve önce başka bir tane eklemem gerekiyordu sudo:

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

jcmdVe gibi diğer komutlarla da çalışır jinfo.


Çift sudogünümü kurtarır!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 hatayı döndürür sudo: jmap: command not found. Java yolunu zaten .bash_profile içinde yapılandırıyorum, ne yapmalıyım.
roamer

@roamer Belki de bunun nedeni, eskullanıcı olarak çalıştırdığınızda , .bash_profileuygulanmıyor olmasıdır (çünkü bash profili kullanıcınızla ilgilidir, sanırım). Ben daha küresel bir şekilde java yolu dahil tavsiye veya benzeri belki komuta java yol belirtin sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283(burada /java/pathjava yoludur ve emin olmasını sağlayın jmapİçinde ).
Lucas Basquerotto

/Home/es/.bash_profile içinde java yolunu yapılandırıyorum ve es kullanıcısı ile oturum açarken jmap kullanabiliyorum. Bu cmd sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283çalışıyor. Çok teşekkürler.
gezici

2

Uygulamanız bir systemd hizmeti olarak çalışıyorsa, altında /usr/lib/systemd/system/ve hizmet adınıza göre adlandırılan hizmet dosyasını açmalısınız . Ardından privateTmp özniteliğinin doğru olup olmadığını kontrol edin .

systemctl daemon-reload systemctl restart [servicename] Doğruysa , bunu false olarak değiştirmelisiniz, ardından aşağıdaki gibi komutu kullanarak servisi yenilemelisiniz: Yeniden başlatmadan önce jmap / jcmd'yi çalıştırmak istiyorsanız, servis dosyasındaki execStop komut dosyasını kullanabilirsiniz. Sadece komut verin ve çalıştırınsystemctl stop [service name]


/Usr/lib/systemd/system/elasticsearch.service'i güncellemeden, privateTmp'yi false olarak ayarlamadan önce şu hatayı aldım: Soket dosyası açılamıyor: hedef işlem yanıt vermiyor veya HotSpot VM yüklenmedi - jmap'i şu şekilde çalıştırıyor olsam bile the
elasticsearch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.