unnamed

Javaとか、http://twitter.com/sugarlife

JavaでFull GCを実行する方法

Full GCを任意のタイミングで実行させ、負荷の高い処理に備えておくという戦略を取りたい時がたまにあります。基本的にはチューニングで解決すべきですが、緊急or暫定策の備忘録として。

jmap -histo:live <pid>

LinuxはJDK5から、WindowsはJDK6から利用可能。生存中のオブジェクトのみ抽出したメモリーマップを作成するために、直前にFull GCを実行するのでこれを利用する。
対象のJavaプロセスを実行しているユーザで実行する必要があるので注意。

jcmd <pid> GC.heap_dump <output_filename>

Linux、WindowsともにJDK7から。これも上のjmap -histo:live と同じく、生存中のオブジェクトのみ抽出するためにFull GCを実行する。これもJavaプロセス実行ユーザと同じユーザで実行する。

Full GCを実行する機能について

JDKでは、恐らく上記の生存オブジェクトのヒープ情報を取得する(HeapInspection)場合でしか、明示的にFull GCを実行する方法は準備されていないと思われる。
実際に呼び出されるコードは以下。

./hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
VM_GC_HeapInspection(outputStream* out, bool request_full_gc, bool need_prologue)から以下を呼ぶ
VM_GC_Operation(0 /* total collections, dummy, ignored */,
                GCCause::_heap_inspection /* GC Cause */,
                0 /* total full collections, dummy, ignored */,
                request_full_gc /* live=true, all=false */) 

GCを起動させる方法(追記)

以下はGCが実行され、条件によってはFull GCが呼ばれる。これは上のVM_GC_Operationとは別ルートで、この記事のコメントにあるルートで呼ばれる。条件については未確認なので注意。条件についてはとは書いているが、基本的に Full GC になることを期待できる…はず。

  • Runtime.getRuntime().gc() / System.gc()
  • jcmd <pid> GC.run
  • jconsole の 「Perform GC」ボタン

以下は上のJVM_GC_OperationでFullGCがリクエストされない形で呼ばれるため、普通のGCが起動される。GCなのでヒープ状況次第ではFullGCも呼ばれる。

  • jmap -histo <pid>