Perm領域不足
"java.lang.OutOfMemoryError"が発生しているシステムの相談を受けたのだが、調べてみると純粋にヒープが足りないのではなく、通常は早い段階でサチるはずのPerm領域が原因で発生していることが解った。
どうせプリコンパイルしたJSPクラスが大量にロードされているんじゃないかと思ったのだが、そうではなく、プロファイルの結果では以下のクラスのインスタンスが原因ではないか、という結論になった。
sun.reflect.GeneratedConstructorAccessorXXX sun.reflect.GeneratedMethodAccessorXXX
こんなクラス見たことないが、どうやらリフレクションでJVMが一時的に生成するものらしい。しかし、なぜリフレクションの度にこいつらが生成されるのか皆目見当がつかない。
いずれにせよ動的に生成されるクラスであり、ロードされて次第にPerm領域を圧迫していくのでたちが悪い。(強制FullGCを実行することでアンロードすることは可能)
この動的プログラミング真っ盛りの時代にリフレクションを使うなという時代錯誤的な対応はしたくないが、かといって解決策も見つかっていない。困った。
追記:
以前、Attatch APIに言及した際にコメント頂いたこともあるskさんにPerm領域のチューニングに関しての記事へのリンクを教えて頂いた。
Permanent領域のチューニング/第6回 HotSpot VMの特長を知る 2/2 - @ITjavaパフォーマンスチューニング
症状からして
デフォルトクラスローダでロードしたクラスや、ロードに使用したクラスローダへの参照が残っているクラスの場合、フルGCが実行されてもその対象とはなりません
ロードされているクラスはsun.reflectパッケージなので、この辺が怪しそうだ。