2009-06-10 13 views
4

JVMの実際のオーバーヘッドが、まったく使用されない余分なクラスをロードするためにどのようになっているのか、現在疑問に思っています。不要なJavaクラスをロードする

特定のインターフェイスを実装するクラスを見つけるために、クラスパス内のすべてのクラスを繰り返し実行するコードがあります。

これにより、カスタムクラスをディレクトリにドロップしてロードして登録することができます。

サイドパスの影響は、クラスパス内のすべてのクラスをヒットしてクラスをロードすることです。 JVMのメモリに与える影響は?

クラスをロードするだけで、メモリにはまったく影響がありますか?

答えて

4

いつものように、私はあなたの特定のシナリオでこれを測定することをお勧めします。

私は、全体のクラスパスのスキャンをアドバイスするとは思わないと言っています。クラスパスを制御していない場合(あなたの顧客のものなど)、潜在的に何かを追加する可能性があり、プロセスがクラスパスにドロップしたものをスキャンしようとします(アプリとは無関係かもしれません)。

クラスをアップロードできる特定のディレクトリ/リポジトリだけを指名することをお勧めします。そうすれば、クラスパスのスキャンを制限し、意図しないものを拾う機会を減らすことができます。

+0

おそらく、顧客が実装できるさまざまな種類のクラスに対して別々の場所を持つことが最善の方法です。 –

0

はい、これにより、VMはクラスファイルをロードして検査します(パフォーマンス上の問題があります)。さらに、Sun VMを使用している場合、これらのクラスは永遠にメモリに残ります。特別なオプションを指定しなければ、Sun VMはクラスをいわゆる "PermGen"スペースに入れます。このスペースはガベージコレクションされません。

だから、これは一般的に悪い考えですが、2つの単純な回避策があります。

  1. クラス(ファイル名)の名前を確認してください。名前のインターフェイスの名前を繰り返します。読み込む必要があるものとないものを簡単に気付くことができます。

  2. 2つのディレクトリを使用します。 1つは普通のクラスを含み、もう1つはいつもロードしたいクラスです。

+1

- システムクラスローダによってロードされたクラスのみをアンロードすることはできません。 –

+0

なぜ、独自のクラスローダーに付属するGroovyを使って開発するときに、たくさんのOutOfPermGenを取得しましたか? –

2

あなたがそれらのクラスまたはそれらのインスタンスへの参照を作成しないvery carefulをこれらのクラスをロードするために別々のクラスローダを使用している場合は、そのクラスローダは、ガベージコレクションの対象となり、そのクラスを行うとき。

したがって、すべてのクラスをロードして保持したいクラスを特定し、実際にクラスを使用する別のクラスローダーで2回パスすることで、PermGenスペースが不必要に詰まるのを避けることができます。

1

このようにClassLoadersを使用しても意図しない副作用がありますか?静的な初期化プログラムの実行など。

ServiceLoaderメカニズムを使用できますが、それが適合しない場合は、クラスローダーを使用せずにクラスを検査できます。BCELASMなどのバイト操作ライブラリを使用してクラスを検査できます。

+0

はい、静的な初期化子を呼び出すときの痛みです。そのあまりにも過去にいくつかのデッドロックが発生しました:( –

+0

あなたが制御しないクラスで静的初期化子がやっていることを知っていますね! –

0

「遠いそこに」A案:

あなたが同じことを行うが、実際にVMを使用せずにできますか?クラスファイルの仕様は文書化されていますが、クラスファイルを読み込んで実際に読み込まずにインターフェースを実装しているかどうかを知るために独自のアプリを書くことはできませんでしたか?

これで、クラスや静的インターシアターなどのロードを心配することなく、すべてのディレクトリをスキャンできるようになります。

関連する問題