4

現在、JVMでの実際のオーバーヘッドは、使用されない追加のクラスをロードするためのものであるかどうか疑問に思っています。

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

これにより、カスタムクラスをディレクトリにドロップするだけで、ロードおよび登録できます。

副作用は、クラスパス内のすべてのクラスにヒットし、クラスがロードされることです。JVMメモリにどのような影響がありますか?

クラスをロードするだけでメモリに大きな影響がありますか?

4

5 に答える 5

4

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

そうは言っても、クラスパス全体をスキャンすることをお勧めするかどうかはわかりません。クラスパス(顧客など)を制御しない場合、クラスパスに何かが追加される可能性があり、プロセスはクラスパスにドロップしたもの(おそらくアプリとは無関係)をスキャンします。

クラスをアップロードできる特定のディレクトリ/リポジトリのみを指定することをお勧めします。そうすることで、クラスパススキャンを制限し、意図しないものを誤って取得する可能性を減らすことができます。

于 2009-06-10T09:01:49.883 に答える
2

別のClassLoaderを使用してこれらのクラスをロードし、それらのクラスまたはそれらのインスタンスへの参照を作成しないように細心の注意を払っている場合、ClassLoaderがガベージコレクションの対象になると、クラスも同様になります。

したがって、別々のClassLoaderで2つのパスを実行することにより、PermGenスペースを不必要に詰まらせることを回避できます。1つはすべてのクラスをロードして保持するクラスを識別し、もう1つは実際にそれらを使用します。

于 2009-06-10T09:14:48.500 に答える
1

この方法で ClassLoaders を使用すると、意図しない副作用が発生しませんか? 静的イニシャライザの実行など。

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

于 2009-06-10T09:49:48.180 に答える
0

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

したがって、これは一般的に悪い考えですが、2つの簡単な回避策があります。

  1. クラス名(ファイル名)を確認してください。名前にインターフェイスの名前を繰り返して、ロードする必要があるものとロードしないものを簡単に確認できるようにします。

  2. 2つのディレクトリを使用します。1つには通常のクラスが含まれ、もう1つには常にロードするすべてのクラスが含まれます。

于 2009-06-10T09:02:29.010 に答える
0

「遠く離れた」提案:

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

これにより、任意のディレクトリをスキャンできますが、クラスや静的初期化子などをロードする心配はありません。

于 2009-06-10T17:44:01.030 に答える