そのため、リモートボックスでjmapを使用してヒープを調べており、ガベージコレクションを強制的に実行したいと考えています。 jvisualvmやjconsoleや友人にアクセスすることなく、これをどのように行いますか?
ガベージコレクションを強制的に実行するべきではないことを知っています。ヒープが大きくなっている理由を理解する必要があります。
また、System.GC()が実際にガベージコレクションを強制しないことも理解しています。GCに発生させたいことを伝えるだけです。
これを簡単に行う方法はありますか?不足しているコマンドラインアプリはありますか?
これは、無料の 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またはPerlのopen3でpopen2を使用しました。
UPDATE:ここにjmxtermを使用したワンライナーがあります:
echo run -b Java.lang:type=Memory gc | Java -jar jmxterm-1.0-alpha-4-uber.jar -n -l Host:port
JDK 7以降では、次のようなJDKコマンドツール「jcmd」を使用できます。
jcmd <pid> GC.run
jmap -histo:live <pid>
、それは何も印刷する前にヒープに完全なGCを強制します。
ser319849 の回答への追加。このコマンドを実行すると、次のエラーメッセージが表示される場合があります。
$ 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
...
これは this stackoverflow answer の助けを借りて解決できます
Sudo -u <process_owner> jcmd <pid> GC.run
ここで、<process_owner>
は、PID <pid>
でプロセスを実行するユーザーです。 top
またはhtop
から両方を取得できます
他にもいくつかの解決策があります(ここには既に多くの良い解決策があります):
gc()
を呼び出します。gc()
操作を実行します。次の例は、cmdline-jmxclient用です。
$ Java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'Java.lang:type=Memory' gc
これは、1行しかないため、非常に簡単です。スクリプトに簡単に挿入できます。
同じコマンドラインオプションがあるとは思わない。
同じためにjvisualvm/jconsoleを使用する必要があります。
これらのツールを使用して、プログラムのメモリが多い理由を特定することをお勧めします。
とにかくGCを強制するべきではありません。GCアルゴリズムを確実に妨害し、プログラムを遅くするからです。
アプリケーションで jolokia を使用している場合、次のコマンドでガベージコレクションをトリガーできます。
curl http://localhost:8558/jolokia/exec/Java.lang:type=Memory/gc