閉じる

HeapWorker is wedged: 10970ms spent inside LXXXX.finalize()V

よくわからないのだけど、以下のような処理で XXXX.finalize()が駄目っぽく、10秒でタイムアウト?みたいなエラー。

XXXX xxxx=new XXXX();
try{
foo(); // 時間のかかる処理
}finally{
xxxx.close();
}

finalize()に書いてる処理自体は foo()の中で完結するのでそっちへ持っていったら通るようになった。
なったけど、こういう処理自体はおかしくも何ともないはずなのでモヤモヤ感が。
ワーカースレッドでの処理というのが問題なのかなぁ?

2011/12/21追記

他の調べ物をしていたときにAndroidコードスタイルガイド 日本語訳に行き着き、目に付いたことが。

  1. 例外: 説明なしに、例外をキャッチしながら無視してはいけません。
  2. 例外: 汎用の Exception をキャッチしてはいけません。ただし、スタックのルートにあるライブラリコードの場合は除きます。
  3. ファイナライザ: 通常、ファイナライザを使ってはいけません。
  4. インポート: インポートはうまく限定してください。

なるほど。

2013/02/23追記

以下のように警告が続いた後にエラーで落ちる事例が。

02-23 22:46:27.001: W/dalvikvm(1271): HeapWorker may be wedged: 6013ms spent inside Landroid/database/sqlite/SQLiteCompiledSql;.finalize()V
02-23 22:46:30.051: W/dalvikvm(1271): HeapWorker may be wedged: 9058ms spent inside Landroid/database/sqlite/SQLiteCompiledSql;.finalize()V
02-23 22:46:34.351: E/dalvikvm(1271): HeapWorker is wedged: 13356ms spent inside Landroid/database/sqlite/SQLiteCompiledSql;.finalize()V

どうも、トランザクション処理に 10秒以上かかった末に件のエラーになっているらしい。
SQLiteCompiledSqlの finalizeがデータベースをロックしようとするもトランザクション処理中で待たされ、タイムアウトって落ちっぽく。

SQLiteCompiledSqlの finalizeと言うことは、当該データベースに関連する SQLiteStatementオブジェクトを開放しようとしているのだろうと見当を付け、処理中に SQLiteStatementオブジェクトが開放されないようにコードを修正したところ、警告もエラーも発生しなくなった。

結局、ガベージコレクションを阻害するようなコーディングは行うなと言うことか。

2011/12/21の追記を見るに、finalizeメソッドを定義したクラスのオブジェクトの挙動が~という投稿だったはずだけど、最初のコードがどう結びつくのかわからんな。

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)