非大域ゾーンでメモリ制限をかけてもJVMは大域ゾーンのメモリ最大値を見る

capped-memoryでメモリ、スワップに制限をかけた非大域ゾーンでもJVMを動かしても、JVMがサーバクラスマシンの検出(参考:Oracle Technology Network for Java Developers)のために使用しているメモリのサイズは(capped-memoryされていない)大域ゾーンのメモリ量、つまり物理メモリ量っぽい。この副作用で、最大メモリ使用量が2Gしかないゾーン上で、JVMのデフォルト最大ヒープサイズが1GBになるケースが出てくる(VMのデフォルトヒープサイズ - ihirokyの日記)。


物理メモリが64GB、capped-memoryでphysical=2Gと設定されているゾーンで-XmxオプションなしでJVMを起動すると必ず十分なヒープが取れないと起こられる。-Xmxで適当に制限してやれば大丈夫。以下そんなゾーン上でのJVM起動例。

$ /usr/sbin/prtconf | grep Memory
prtconf: devinfo facility not available
Memory size: 65536 Megabytes
$ java -version
Error occurred during initialization of VM
Could not reserve enough space for object heap
$ java -Xmx64M -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) Server VM (build 14.0-b16, mixed mode)


加えて、他のマシンでメモリ/スワップ = 2G/2Gで動いていたビルドをこのマシンのゾーンに持ってくるとスワップ4G位じゃENOMEM(errno=12)が発生してしまうケースがみられた。JVMのヒープのとり方をうらむべきか、Solarisゾーンの中途半端なゾーン仕様をうらむべきか…。それともサーバリソースをけちらず使えというお告げなんだろうか。