Kabuktan Çöp Toplamaya Nasıl Zorlanırsınız?


106

Bu yüzden uzak bir kutuda jmap bulunan bir yığına bakıyorum ve onun üzerinde çöp toplamaya zorlamak istiyorum. Bunu jvisualvm veya jconsole ve arkadaşlara girmeden nasıl yaparsınız?

Çöp toplamaya zorlama pratiği yapmamanız gerektiğini biliyorum - sadece yığının neden büyük / büyüdüğünü anlamalısınız.

Ayrıca System.GC () 'nin aslında çöp toplamayı zorlamadığının farkındayım - sadece GC'ye bunun olmasını istediğinizi söyler.

Bunu kolayca yapmanın bir yolu var mı? Eksik bir komut satırı uygulaması var mı?


Yanıtlar:


25

Bunu ücretsiz jmxterm programı ile yapabilirsiniz.

Şöyle ateşleyin:

java -jar jmxterm-1.0-alpha-4-uber.jar

Oradan bir ana bilgisayara bağlanabilir ve GC'yi tetikleyebilirsiniz:

$>open host:jmxport
#Connection to host:jmxport is opened
$>bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
$>run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns: 
null
$>quit
#bye

Bunu bash / perl / ruby ​​/ diğer komut dosyalarına yerleştirme hakkında bilgi için jmxterm web sitesindeki dokümanlara bakın. Bunu yapmak için Python'da popen2 veya Perl'de open3 kullandım.

GÜNCELLEME: işte jmxterm kullanan tek satırlık bir:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port

346

JDK 7'den beri JDK komut aracını 'jcmd' kullanabilirsiniz, örneğin:

jcmd <pid> GC.run


22
Neden bana bunlardan bahsetmiyorsunuz? :)
noahlz

2
"AttachNotSupportedException: Soket dosyası açılamıyor" mesajı alırsanız, bu yanıta
eklememe

Ve eğer alıyorsanız Explicit GC is disabled, no GC has been performed, bu -XX:+DisableExplicitGCVM argümanından kaynaklanıyor olabilir . Bakınız: mail.openjdk.java.net/pipermail/serviceability-dev/2017-August/…
Eyal Roth

Bu yalnızca Oracle JDK için çalışacak, open-jdk için çalışmayacaktır.
Ali Saleh

104

Çalıştırırsanız jmap -histo:live <pid>, herhangi bir şey yazdırmadan önce yığın üzerinde tam bir GC zorlar.


3
tüm javalarda çöp toplama yapmaya zorlayın: ps axf | grep java | grep -v grep | awk '{print "jmap -histo: live" $ 1}' | sh
gtrak

1
Bu nerede belgelendi? Ya olmadan: canlı (örneğin -F gerekli olduğunda)?
nafg

7
2014'ün gizemli geleceğinden merhaba. jcmdArtık iş için doğru araç.
noahlz

16

User3198490 'ın cevabına ek . Bu komutu çalıştırmak size aşağıdaki hata mesajını verebilir:

$ jcmd 1805 GC.run    
[16:08:01]
1805:
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
...

Bu, bu yığın aşımı cevabının yardımıyla çözülebilir

sudo -u <process_owner> jcmd <pid> GC.run

<process_owner>işlemi PID ile çalıştıran kullanıcı nerede <pid>. Her ikisini de alabilirsin topveyahtop


Ya aşağıdakiler? Aynı şey? java.io.IOException: Operation not permitted
dhokey

Bu hata mesajıyla henüz karşılaşmadım. Belki işe yarar sudo -u <process_owner> jcmd <pid> GC.run, deneyebilir misin? Komut güvenli olmalı
Thomas Rebele

Yapardım ama o makinede sudo erişimim yok.
dhokey

Araç düzgün çalışıyor. İşletim sisteminde onu yürütmek için doğru izinlere sahip değilsiniz. Aynısı, Java kullanmasa bile diğer uygulamalar için de geçerlidir.
aled

6

Birkaç başka çözüm var (burada zaten birçok iyi çözüm var):

Aşağıdaki örnek cmdline-jmxclient içindir:

$ java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'java.lang:type=Memory' gc

Bu güzel çünkü sadece bir satır ve onu bir senaryoya gerçekten kolayca koyabilirsiniz.


5

linux için:

$ jcmd $(pgrep java) GC.run

jcmdJDK ile paketlenmiştir $(pgrep java), java işlem kimliğini alır


Bu yalnızca görünen bir java işlemi çalışırken işe yarar. Aksi takdirde, ikinci PID'yi jcmd için komut olarak yorumlayacaktır ki bu açıkça tanınmaz ve bir hata verir.
Cas Eliëns

0

Bunun için herhangi bir komut satırı seçeneği olduğunu sanmıyorum.

Aynı şekilde jvisualvm / jconsole kullanmanız gerekecek.

Bu araçları, programınızın neden hafızada yüksek olduğunu belirlemek için kullanmanızı öneririm.

Her neyse, kesinlikle GC algoritmasını bozacağı ve programınızı yavaşlatacağı için GC'yi zorlamamalısınız.


0

Uygulamanızla birlikte jolokia kullanıyorsanız , bu komutla bir çöp toplama işlemini tetikleyebilirsiniz:

curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc

-10

sadece:

kill -SIGQUIT <PID>

4
Bu, çöp toplamayı değil yığın dökümünü tetikleyecek
Dror Bereznitsky

en azından solaris, bir GC kuvveti yapar.
Amin Abbaspour

2
Solaris'te bile, SIGQUIT ne bir GC ne de bir yığın dökümünü tetiklemez. SIGQUIT, yalnızca HotSpot için bir iş parçacığı dökümü tetikleyecektir. IBM JVM için yapılandırılabilir.
Mircea Vutcovici

GC'yi tetiklemez, sadece yığın izini yazdırın.
Elad Tabak
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.