2

停止および再起動せずに、それ自体の一部 (一度に 1 つのクラス) を更新する機能を必要とするアプリケーションがあります。JavaCompiler API を使用すると、変更されたクラス ソース コードの生成、再コンパイル、ロード、およびクラスのインスタンス化を簡単に行うことができます。これはすべてメモリ内で実行できます (ディスクまたはネットから読み取られるファイルはありません)。

アプリケーションは、そのようなクラスの複数のオブジェクトをインスタンス化することはありません。そのオブジェクトへの参照は 2 つまたは 3 つしかありません。変更されたクラスがロードされてインスタンス化されると、それらの参照はすべて新しいオブジェクトに変更されます。また、変更されたクラスのロード中に、影響を受けるクラスのメソッドが別のスレッドで実行されていないこともおそらく保証できます。

私の質問は次のとおりです。私のクラスローダーは、以前にロードしたクラスと同じ名前の変更されたクラスをロードする際に問題がありますか?

ロードされたクラスのキャッシュをクラスローダーに明示的に実装しない場合、問題を回避できますか? または、親クラス ローダーへの委譲が問題を引き起こす可能性はありますか?

クラス ローダーの単一のインスタンスを使用したいと考えていますが、必要に応じて、クラスを更新するたびに新しいインスタンスを作成できます。

注: OSGI を調べたところ、必要以上に多すぎるようです。

4

2 に答える 2

1

これに関する便利な例がhttp://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.htmlにあります

私たちはかなりの量の動的なクラスのリロードを行っています (コンパイルに Groovy を使用しています)。クラスの依存関係がある場合は、リロード時にこれらの依存関係を再コンパイルする必要がある場合があることに注意してください。開発スタックでは、これらの依存関係を追跡し、依存関係が古くなるたびに再コンパイルします。本番スタックでは、リロードしない ClassLoader を選択し、何かが変更されるたびに新しい ClassLoader を作成しました。したがって、どちらの方法でも実行できます。

ところで - GroovyScriptEngine はhttp://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.5/groovy/util/GroovyScriptEngine.java#GroovyScriptEngineにあります。彼らがどのようにそれを行うかを掘り下げたい場合は興味深い.

于 2012-03-16T17:02:23.083 に答える
0

新しいクラスをロードすると、適切なテーブルのクラス名が置き換えられ、メモリが GC されるはずですそうは言っても、重要なクラスをコンパイルしてそれを置き換える、たとえば10,000回の実際の短いプログラムを使用して、厳しいテストを行うことになります。

于 2012-02-15T17:37:11.717 に答える