-これは何?
reflectionを行うときの ByteCode Accessor
-は?
アクセッサーには2種類あり、JNI AccessorとByteCode Accessor
ご存知のようにJNI操作はコストが高いので、頻繁に呼び出されるとJNIからByteCodeへ昇格される
そうすることで、reflectの動作を高速化させている。
これが導入されたのはJRE1.4x以降
-このクラスをロードしたとか消したとかでまくるんだが、ぉぃい
reflectAPIの呼び出し単位で作成されてしまうので、フレームワークなんかを
使っているともう吐き気するぐらい作成される。
ClassオブジェクトなのでJVMのバージョンによってはHeapの中では厄介ものである
(フラグメント要因になる)。
だが安心してほしい。弱参照状態で作成され、参照は親のClassLoaderだけなので、
「使用中」でなければ破棄できる。
破棄されたものは、再びJNI Accessorからの出直しになる。
-それって、パフォーマンス元に戻るんじゃね?意味なくない?
パレートの法則。80:20の法則。
GC対象になるようなAccessor = 未使用 =20%部分じゃない =パフォーマンスに影響を与えない
パフォーマンスチューニングにおける大前提である。
-制御したいんだが
-D sun.reflect.noInflation = false (default value is false)
-D sun.reflect.inflationThreshold = 15 (default value is 15)
noInfration =true は進化をやめよ、となり、デフォルトでbyteCodeAccessorが作成される
よって、マッハになるかもしれないがsun.reflect.Generatedほげほげの数は増える
inflationThreshold は進化までの回数。デフォルトでは15回呼ばれるとHot判定になりbyteCodeAccessorが作成される
普通はこんなコアな設定はさわらんでよろしい。
その前に直すべき箇所があるはずである。
参考リンク
https://www.ibm.com/developerworks/mydeveloperworks/blogs/738b7897-cd38-4f24-9f05-48dd69116837/entry/reflection_a_memory_viewpoint3?lang=ja
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
http://stackoverflow.com/questions/2971019/how-to-avoid-generatedserializationconstructoraccessor-problems
IBM系はJNIから進化できなくなりByteCodeAccessorが生成されなくなり、速度を犠牲にしてメモリインパクトが減る。
Oracle系は即時進化に変わるのでIBMのそれと真逆の動きになる。
IBMと同じようにJNI固定したい場合は、 Integer.MAX_VALUE にする。
IBM系をOracleのように即時進化にしたい場合は、
sun.reflect.noInflation=trueを使う。
本文にもあるけど、ほとんどのケースではこんな設定気にする必要はない。