以前、JMXで書いたメモリ使用量の監視プログラムが、監視対象サーバを変えた途端、Exception を吐いて死亡。えええ。
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://myserver:1234/jmxrmi");
JMXConnector conn = JMXConnectorFactory.connect(url);
MBeanServerConnection mbsc = conn.getMBeanServerConnection();
MemoryPoolMXBean mpbean = (MemoryPoolMXBean) ManagementFactory.newPlatformMXBeanProxy(mbsc,
"java.lang:type=MemoryPool,name=Tenured Gen",
MemoryPoolMXBean.class);
んで、エラー。
Exception in thread "main" java.lang.IllegalArgumentException: java.lang:type=MemoryPool,name=Tenured Gen not found in the connection.
at java.lang.management.ManagementFactory.newPlatformMXBeanProxy(Unknown Source)
...
「そんな ObjectName のMBean はコネクションに無いよ」とか言っちゃっているので、どんなもんがリストされているか確認。
ObjectName oName;
Set names = mbsc.queryNames(null, null);
for (Iterator it = names.iterator(); it.hasNext();) {
objectName = (ObjectName) it.next();
System.out.println("ObjectName: " + objectName );
}
そして、暴かれた驚愕の事実。
...
ObjectName: java.lang:type=MemoryPool,name=PS Old Gen
...
Old領域を表す名前が、「Tenured Gen」じゃなくて、「PS Old Gen」になっている。書き直してコンパイルしたら、無事に動作してくれた。ふう。
どうやらJVMが採用するGC方式によって、ここの名前が変わるみたい。JVM1.5系だと、マルチプロセッサ環境では、パラレルGC方式に自動的にスイッチされる。賢い仕様なのだけど、こんなとこにも影響が出るとは。
ということで、環境に応じて適切なプール名称を指定する方法を考えねば…。
続きを読む ""Tenured Gen"と"PS Old Gen""