JVMにはPermanent領域と呼ばれるヒープ領域があります。ここにはクラス定義やメソッド、フィールドなどのメタデータが格納されます。
Permanent領域のデフォルトのサイズは、一般的なアプリケーションにとって十分な大きさに設定されています。しかし、アプリケーションによっては非常に多くのクラスをロードするものもあり、Permanent領域が足りなくなることがあります。例えば、JSPやサーブレットを多用するアプリケーション(アプリケーションサーバなど)は、デフォルトのPermanent領域サイズでは足りなくなり、次のようなエラーが発生することがあります。
$ java ManyClassLoadingTest Permanent generation is full... increase MaxPermSize (current capacity is set to: 67108864 bytes ) Permanent generation is full... increase MaxPermSize (current capacity is set to: 67108864 bytes ) Exception in thread "main" Permanent generation is full... increase MaxPermSize (current capacity is set to: 67108864 bytes ) Permanent generation is full... increase MaxPermSize (current capacity is set to: 67108864 bytes )
このような場合には、Permanent領域のサイズを変更する必要があります。Permanent領域のサイズは、-XX:PermSizeと-XX:MaxPermSizeの2つのオプションで指定できます。単位はバイトです。
$ java ?XX:PermSize=32m ?XX:MaxPermSize=64m TestProg
オプション名 | 意味 | デフォルト値 |
---|---|---|
-XX:PermSize | Permanent Spaceの初期値 | 1MB |
-XX:MaxPermSize | Permanent Spaceの最大値 | 64MB |
Permanent Space のサイズを指定するオプション |
Permanent領域が満杯になると、JVMはフルGCを実行します。それでもPermanent領域の割り当て要求に応えられない場合、Permanent領域を拡張します。このとき、上記オプションで指定したサイズの初期値から最大値まで、必要に応じて拡張されます。
Permanent領域のサイズは、アプリケーションがロードするクラスの数に比例します。そこで、-Xverbosegcオプションを指定してアプリケーションを起動し、必要となるすべてのクラスをロードするようにテストを実施します。この時点のPermanent 領域のサイズを基に-XX:MaxPermSize で指定すれば、上述のエラーの発生を防ぐことが可能です。
Permanent領域の使用量を減らすには、同領域に読み込まれたクラスがガベージ・コレクションの対象となる必要があります。
JVMは、クラスローダを通じてクラスファイルをPermanent領域にロードします。クラスローダには、デフォルトクラスローダとユーザー定義クラスローダの2種類があります。このうちデフォルトクラスローダは、JVMの起動時から用意されているもので、システムクラスはこのクラスローダでロードされます。アプリケーションのクラスも通常はこのクラスローダでロードされます。一方、ユーザー定義クラスローダは、ClassLoaderクラスを継承して新たに作成されたクラスローダです。
Permanent領域のクラスがガベージ・コレクションの対象となるのは、以下の2つを満たす場合に限られています。
つまり、デフォルトクラスローダでロードしたクラスや、ロードに使用したクラスローダへの参照が残っているクラスの場合、フルGCが実行されてもその対象とはなりません(ちなみにJVM起動時に-Xnoclassgcオプションを付けると、Permanent領域全体をフルGCの対象外とすることができます)。
従ってPermanent領域のチューニング作業では、アプリケーションが使用するクラスローダの種類が重要となります。クラスの大半がユーザー定義クラスローダによってロードされていれば、同クラスローダへの参照をできるだけ削除することで、Permanent領域の肥大化を抑制できます。
以上、今回はHotSpot VMのパフォーマンス向上のポイントと、Permanent領域のチューニング方法について紹介しました。
本記事は、HP-UX Developer Edgeに掲載された「連載 Javaパフォーマンスチューニング」を株式会社アットマーク・アイティおよび本記事の筆者が独自の判断のもとに加筆・修正したものです。
Copyright © ITmedia, Inc. All Rights Reserved.