CLOVER🍀

That was when it all began.

実行中のJavaアプリケーションの拡張設定を確認/変更する

jinfoというJDKに付属しているコマンドラインツールを使用すると、Javaの起動オプションやシステムプロパティを確認できたり、「-XX」ではじまる一部の値については実行中に変更できるようです。

詳しい説明は以下に書いてありますが、jstackやjmapなどと同様、使用するには対象のJavaVMのPIDが必要です。
http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/share/jinfo.html

例えば、以下のようなちょっとわざとらしいオプション指定でJavaアプリを起動します。

$ java -Xmx512M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:+PrintGCTimeStamps -XX:+PrintGC -XX:+PrintGCDetails Monitor 

ここで、jpsコマンドでPIDを確認します。

$ jps
6582 Monitor
6608 Jps

例えば、PrintGCオプションが有効かどうか確認してみます。

$ jinfo -flag PrintGC 6582
-XX:+PrintGC

「-flag」オプションの後に、確認したいオプション名を入力すればOKです。この例では、「+」付きの結果が返ってきているので有効、ということですね。

全然関係ない、Concurrent Mark Sweep GCが有効かどうか確認してみると、

$ jinfo -flag UseConcMarkSweepGC 6582
-XX:-UseConcMarkSweepGC

無効だと返ってきます。

また、このアプリの起動時にはGCの情報を出力するようにしていましたが、以下のコマンドを実行すると

$ jinfo -flag -PrintGCDetails 6582

GCの詳細情報が出力されなくなり、さらに以下のコマンドを実行すると

$ jinfo -flag -PrintGC 6582

GCログ自体が出力されなくなります。
ここで、以下のコマンドを実行すると、起動時のようにGCログが出力されるようになります。

$ jinfo -flag +PrintGC 6582
$ jinfo -flag +PrintGCDetails 6582

というわけで、「-flag」オプションに続いて「+」でオプションを有効に、「-」で無効にってことですね。

確認だけなら、フラグ以外のものも指定可能です。

$ jinfo -flag ParallelGCThreads 6582
-XX:ParallelGCThreads=2

さすがに、変更はできないようですが…。

$ jinfo -flag ParallelGCThreads=1 6582
Exception in thread "main" java.io.IOException: Command failed in target VM
	at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:224)
	at sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:217)
	at sun.tools.attach.HotSpotVirtualMachine.setFlag(HotSpotVirtualMachine.java:190)
	at sun.tools.jinfo.JInfo.flag(JInfo.java:123)
	at sun.tools.jinfo.JInfo.main(JInfo.java:76)

その他、コマンドラインで与えたJavaVMのオプションも取得可能です。この場合は、「-flags」オプションを使用します。

$ sudo jinfo -flags 6582 
Attaching to process ID 6582, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.1-b03

-Xmx512M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:+PrintGCTimeStamps -XX:+PrintGC -XX:+PrintGCDetails

このオプションを使用する場合、管理者権限が必要なようですが。

また、「-sysprops」オプションを使用することで、System#getPropertiesなどで取得しているような、システムプロパティについても確認可能です。こちらも、管理者権限が必要なようですが。

$ sudo jinfo -sysprops 6582
Attaching to process ID 6582, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.1-b03
java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = /usr/lib/jvm/java-7-oracle/jre/lib/amd64
java.vm.version = 23.1-b03
java.vm.vendor = Oracle Corporation
java.vendor.url = http://java.oracle.com/
path.separator = :
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg = sun.io
user.country = JP
sun.java.launcher = SUN_STANDARD
sun.os.patch.level = unknown
java.vm.specification.name = Java Virtual Machine Specification
user.dir = /xxxxx/perf_mon
java.runtime.version = 1.7.0_05-b05
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
java.endorsed.dirs = /usr/lib/jvm/java-7-oracle/jre/lib/endorsed
os.arch = amd64
java.io.tmpdir = /tmp
line.separator = 

java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 51.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.2.0-25-generic
user.home = /home/xxxxx
user.timezone = 
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.7
java.class.path = .
user.name = xxxxx
java.vm.specification.version = 1.7
sun.java.command = Monitor
java.home = /usr/lib/jvm/java-7-oracle/jre
sun.arch.data.model = 64
user.language = ja
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.7.0_05
java.ext.dirs = /usr/lib/jvm/java-7-oracle/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /usr/lib/jvm/java-7-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-7-oracle/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-7-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-7-oracle/jre/classes
java.vendor = Oracle Corporation
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = gnome
sun.cpu.isalist =