6

私は面白い問題を抱えています - 私のアプリケーションが長時間 (> 20h) 実行されている場合、時々 NoClassDefFound エラーが発生します - JVM はクラスがとにかく使用されないことを決定し、それを GCd したようです。

もう少し具体的に言うと、以下に例を示します。

object ErrorHandler extends PartialFunction[Throwable,Unit] {
  def isDefinedAt(t: Throwable) = true
  def apply(e: Throwable) =e match {
    // ... handle errors
  }
}

// somewhere else in the code...
try {
  // ... long running code, can take more than 20 hours to complete
} catch (ErrorHandler)

そして、次の例外が発生します。

Exception in thread "main" java.lang.NoClassDefFoundError: org/rogach/avalanche/ErrorHandler$

その try/catch ブロックの実行時間が短い場合、すべてが期待どおりに機能します。

興味のある方は、問題のコードベースをご覧ください: Avalanche

これと同様の問題はCent OS 5、JRE 6u26 と Scala 2.9.1 / 2.9.2 を使用するマシンでのみ見られたことに注意する必要があります。

この問題の原因は何ですか?

4

1 に答える 1

1

クラスを初期化しようとしてメモリが不足した場合、OutOfMemoryまたはNoClassDefが表示されると思いますか?

  //from initialize_impl
  if (NULL == message) {
    // Out of memory: can't create detailed error message
    THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);

コードがOOMをスローした後、例外ハンドラオブジェクトを読み込めなかった可能性があります。

もちろん、他の一時的な状態も考えられます。ネットワークがダウンしていて、クラスがネットワークドライブ上にある。または、テスト中にクラスディレクトリをクリーンアップしました。もう1つの可能性は、大文字と小文字を区別しないファイルシステムでアプリを構築し、異常な名前のクラスファイルを使用して大文字と小文字を区別するファイルシステムでテストしていることです。たとえば、*。classを削除せずにオブジェクト「handler」を「Handler」に変更した場合でも、「Handler.class」は表示されます。(ただし、エラーメッセージの詳細には、名前の競合が含まれていると思われます。もちろん、OOMでない限り。)

AbstractFileClassLoaderを壊そうとする機会はありませんでした。私の以前の推測は次のとおりです。

Avalancheはビルドツールであり、scalacのインスタンスを実行して、build.scalaをscalacのAbstractFileClassLoaderでロードされるメモリ内クラスファイルにコンパイルします。ここで「AbstractFile」は抽象化です。build.scalaはツール構成に影響を与えるため、AFCLがクラスローダーの委任を尊重することが不可欠であることは明らかです。それは本当のようですが、getResourceAsStreamで最初に親に委任されていないことに気付きました(クイックテストで確認されたように)。疑わしいのは、findClassがclassBytesを使用していることです。これは、失敗するとsuperを呼び出します。これは素晴らしいScalaClassLoaderですが、getResourceAsStreamを使用してFoo.classをロードします。したがって、findClassを呼び出すと、親CLからクラスが返される可能性があります(これは間違っています)が、親がすでに失敗していることがわかっている場合は、それは意味がない可能性があります。なぜなら

1日実行されるbuild.scala(またはav.scala)に何が含まれているのかわかりませんが、おそらく、動作に問題のある子クラスローダーによってAvalancheが(再)ロードされ、スローされるとCLが実行できます。 t findClassyourErrorHandler。

于 2012-09-13T11:13:39.103 に答える