シェルからガベージコレクションをどのように強制しますか?


106

だから私はリモートボックスのjmapでヒープを見ていて、それにガベージコレクションを強制したいです。jvisualvmやjconsoleなどに飛び込むことなく、これをどのように行うのですか?

私はあなたがガベージコレクションを強制する習慣になってはいけないことを知っています-ヒープが大きい/大きくなっている理由を理解すべきです。

また、System.GC()が実際にガベージコレクションを強制するのではなく、GCに発生を通知するだけであることがわかります。

とはいえ、これを簡単に行う方法はありますか?一部のコマンドラインアプリが不足していますか?


回答:


25

これは、無料のjmxtermプログラムを介して行うことができます。

次のように起動します。

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

そこから、ホストに接続してGCをトリガーできます。

$>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

これをbash / perl / ruby​​ / otherスクリプトに埋め込む方法については、jmxterm Webサイトのドキュメントを参照してください。私はこれを行うために、Pythonではpopen2、Perlではopen3を使用しました。

更新: jmxtermを使用したワンライナーは次のとおりです。

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

346

JDK 7以降、次のようなJDKコマンドツール 'jcmd'を使用できます。

jcmd <pid> GC.run


22
これらのことを教えてくれませんか?:)
noahlz

2
"AttachNotSupportedException:Unable to open socket file"が表示された場合は、この回答への私の追加を
Thomas Rebele

そして、もしあなたがそれを手に入れてExplicit GC is disabled, no GC has been performedいるなら、それは-XX:+DisableExplicitGCVMの議論によるかもしれない。参照:mail.openjdk.java.net/pipermail/serviceability-dev/2017-August/...
エヤル・ロート

これはOracle JDKでのみ機能し、open-jdkでは機能しません。
Ali Saleh

104

を実行するとjmap -histo:live <pid>、何も出力しないうちにヒープで完全なGCが強制されます。


3
すべてのJavaでガベージコレクションを強制:ps axf | grep java | grep -v grep | awk '{print "jmap -histo:live" $ 1}' | sh
gtrak '19年

1
それはどこに文書化されていますか?:liveなしでどうですか(例:-Fが必要な場合)?
nafg 2014

7
2014年の神秘的な未来からこんにちは。 jcmd今は仕事に適したツールです。
noahlz 2014

16

user3198490の回答への追加。このコマンドを実行すると、次のエラーメッセージが表示される場合があります。

$ 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
...

これは、このスタックオーバーフローの回答の助けを借りて解決できます

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

ここ<process_owner>で、PIDでプロセスを実行するユーザーです<pid>topまたはから取得できますhtop


以下についてはどうですか?同じこと? java.io.IOException: Operation not permitted
dhockey

このエラーメッセージはまだ発生していません。多分それはで動作しますsudo -u <process_owner> jcmd <pid> GC.run、あなたは試すことができますか?コマンドは安全でなければなりません
Thomas Rebele

そのマシンにはsudoアクセスはありますが、ありません。
dhockey 2018

ツールは正しく動作します。オペレーティングシステムでそれを実行するための適切な権限がありません。Javaを使用しない場合でも、同じことが他のアプリケーションにも当てはまります。
18

6

他にもいくつかの解決策があります(すでに多くの優れた解決策があります)。

  • アクセスするには、少しのコード書きMemoryMBean、コールをgc()
  • コマンドラインJMXクライアント(cmdline-jmxclientjxmtermなど)を使用gc()して、MemoryMBeanで操作を実行する

次の例は、cmdline-jmxclientの場合です。

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

これは1行だけであり、スクリプトに非常に簡単に挿入できるので便利です。


5

Linuxの場合:

$ jcmd $(pgrep java) GC.run

jcmdJDKとともにパッケージ化され、$(pgrep java)javaのプロセスIDを取得します


これは、実行中のJavaプロセスが1つある場合にのみ機能します。それ以外の場合、2番目のPIDは、明らかに認識されないjcmdのコマンドとして解釈され、エラーがスローされます。
CasEliëns

0

同じためのコマンドラインオプションはないと思います。

同じためにjvisualvm / jconsoleを使用する必要があります。

これらのツールを使用してIDを特定することをお勧めします。プログラムがメモリ不足の理由です。

とにかく、GCアルゴリズムを妨害してプログラムを遅くするので、GCを強制するべきではありません。


0

アプリケーションでjolokiaを使用している場合は、次のコマンドでガベージコレクションをトリガーできます。

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

-10

ただ:

kill -SIGQUIT <PID>

4
これにより、ガベージコレクションではなく
ヒープダンプ

少なくともソラリスはフォースGCです。
Amin Abbaspour 2014

2
Solarisでさえ、SIGQUITはGCもヒープダンプもトリガーしません。SIGQUITはHotSpotに対してのみスレッドダンプをトリガーします。IBM JVMの場合は構成可能です。
Mircea Vutcovici

GCをトリガーせず、スタックトレースを出力します。
Elad Tabak
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.