日々精進

新しく学んだことを書き留めていきます

Javaアプリの起動引数-Xmsで指定したメモリ量とJavaアプリが使用しているメモリ量が異なる。

よくあるプラクティスとして-Xmsと-Xmxの値を同じにしてJavaアプリ起動時に一括でメモリを確保させるというのがある。 それをやると、Javaアプリ起動時から常に一定量のメモリが使用中になると思っていたがそういう挙動にならなかったのでその原因を調査した。

factは以下。

  • -Xms6g -Xmx6g を起動引数に設定した
  • cat /proc/meminfoでOSのメモリ使用量を調べたところ6GB未満だった

調査した結果は以下。

-Xms, -Xmxの挙動はOSによって異なる。Linuxの場合vm.overcommit_memoryオプションの設定によっても異なる。 参考: stackoverflow.com

オーバーコミット有効の場合、mallocしても実メモリは確保されない(=つまり、cat /proc/meminfo のMemAvailableが減らない?) 参考: passingloop • Linux のオーバーコミットについて調べてみた

以下のHPに 「overcommit memory機能」が有効な場合、Linuxは、Javaヒープの各領域の最大値に相当する仮想メモリ資源を、Java VMの起動時に、Javaプロセスに対して予約します。 という記載がある。つまり、「予約」するだけで他のプロセスが使えなくなるわけではなさそう。 software.fujitsu.com

メモリには「UNMOVABLE」「RECLAIMABLE」「MOVABLE」「RESERVE」の4種類がある。上記の「予約する」というのはメモリにRESERVEマークを付けるということ? 参考: www.atmarkit.co.jp

-Xmsと-Xmxが指定するのはメモリ割り当てプールという領域。これ以外にPermanent世代領域というのもある 参考: software.fujitsu.com