8

最近、Swing アプリケーションを Webstart に変換しました。プロセスは非常に簡単でしたが、すべてのウィンドウを閉じた後、アプリケーションの JVM が終了しないことがわかりました。スレッド ダンプは、いくつかの非デーモン スレッド、特に Swing の EDT、AWT、およびいくつかの websart 関連のスレッドがあることを示しました。

使用される実際の戦略は、各ウィンドウが作成されるときにカウンターを増やし、閉じるときにカウンターを減らすというものです。デフォルトのクローズ操作は DISPOSE_ON_CLOSE です。カウンターがゼロになったら、すべてのスレッドプールを停止し、すべての JNI リソースを解放します。

Bat ファイル (同じ JAR) からアプリケーションを起動すると、すべてのウィンドウが閉じられたときに正常に終了したため、問題は Webstart に関係していると考えました。

今質問:

  1. 正確に何が起こっているのか誰か教えてもらえますか? Webstart がゾンビ JVM を残すのはなぜですか?
  2. JVM を停止せずに Webstart リソースを明示的に解放する方法はありますか?
  3. System.exit() を呼び出すと、リソースを解放せず、後でクリーンアップするために OS に依存するというずさんな慣行が助長されるという意見を常に持っていました (後でコードを再利用すると、厄介な驚きにつながる可能性があります)...私は何かを逃していますか?

アプリが Webstart によって起動されたかどうかを検出するためのフォローアップの質問も参照してください。

4

5 に答える 5

6

はい、WebStart のバグのためです。WebStart は、EDT と対話する独自の目的のために「セキュア スレッド」を開始します。この SecureThread は、すべてのウィンドウと AWT リソースが破棄されたときに想定される Java プロセスの自動終了を防ぎます。

詳細については、http://www.pushing-pixels.org/?p=232を参照してください。

于 2008-10-17T19:36:16.547 に答える
1

通常、AWT EDT が原因です。ここ数年、未処理のウィンドウがない場合にシャットダウンするロジックがいくつかありました。ただし、AWT および Swing の実装内を含め、リークに関する問題が繰り返し発生します。したがって、本番リリースでは System.exit を使用することを強くお勧めします (リークを検出するためのテストでは、これを省略したい場合があります)。

システム ウィンドウ (コンソール、javax.jnlp サービス、およびその他のダイアログ) が表示されていない場合、WebStart スレッドはすべてデーモンである必要があります。

于 2008-10-17T13:22:48.813 に答える
0

jconsole に接続することを検討し、JVM が何をしているかを調べてください。

于 2009-02-17T19:45:37.577 に答える
0

Web Start でも同じ問題が発生します。Java コンソールをオフにしても、プロセスはハングアップしません。Sun から既知のバグ ID はありますか?

于 2009-03-03T15:27:19.860 に答える
0

Webstart はコンソール ウィンドウを起動します (これを無効にできる場合があります)。コンソール ウィンドウは、webstart プロセスの stdout/err と基本的なログ/デバッグを表示するために使用されますが、トップレベルの AWT/Swing ウィンドウが作成されるという副作用があります。AWT/EDT は LAST ウィンドウが破棄されたときにのみ終了するため、コンソール ウィンドウはアプリケーションを保持しています。アプリケーションが終了することを 100% 確実にするために、おそらく System.exit() を呼び出す必要があります (特定のクライアント構成を保証できない限り、webstart コンソールはオフになっています)。

于 2008-10-17T13:09:01.243 に答える