2009-07-02 6 views
0

Webサーバーから画像をダウンロードしてユーザーに表示するJavaアプレットを作成しています。 Java 1.6.0_3以降では正常に動作しますが、古いバージョンでは20ページビューごとに1回程度プロセスが完全にクラッシュします。プロセスが完全にフリーズしているため、Javaコンソールにエラーメッセージはありません。私は時々約15分待っていましたが、決して凍りつくことはありません。getInputStreamを呼び出すとJava URLConnectionがプロセス全体をクラッシュさせます

すべてのコード行の後にデバッグメッセージを追加し、クラッシュを引き起こしている行がInputStream data = urlConn.getInputStream()であることを確認しました。

urlConnは、ロードしたい画像をポイントしているURLConnectionオブジェクトです。私は考えることのできるオプションのすべての組み合わせを試しましたが、何も助けません。私はJavaのバグデータベースや1.6.0_3のリリースノートで何かを見つけることができませんでした。

誰もこの問題が発生しましたか?どのようにそれを修正するための任意のアイデア?それは本当に全体のJVMの凍結のプロセス、または何か他のものであるかどうかを決定する

+0

それは可能性がありますWiresharkを使ってこのアプレットとの間でやりとりされるネットワークトラフィックをキャプチャするのは興味深いことです。 –

+0

あなたはどのタイプのURLConnectionを使用していますか? getInputStream()メソッドがURLConnection基本クラスに実装されていないため、使用している実装を切り替えると違いが生じる可能性があります。 –

答えて

1

(1)Javaのスタックダンプ(SIGQUIT/CTRL-ブレーク/ jstack)を取得

(2)していますあなたが観察できる何かをしている別のバックグラウンドスレッド。それは止まるのですか?

(3)フリーズ中に別のプロセス(ブラウザなど)がサーバーに接続できるかどうかを確認しますか?

ランダムに20回ごとにフェッチする(たとえば、時間の5%、JVM実行時に最初にフェッチすることがある)、または常に約20フェッチ後に?後者の場合は、何かが適切に閉じられていないように聞こえる。

Linux上では、 'netstat -t'または 'lsof'(特定のオプションを指定するか、いくつかの行だけを表示するようにgrepped)を使用してオープンソケットを見ることができます。それぞれのフェッチ後に1つ以上が開いていて、カウントが決して下がらないなら、あなたは物事を適切に閉じていません。

もしそうなら、各tryの後にHttpUrlConnectionで戻るストリームおよび/またはdisconnect()を呼び出すと、そのストリームでclose()を呼び出すことが役に立ちます。 (アプレットが開くことができる接続の数にはさらに厳しい制限があるかもしれないので、スタンドアロンのアプリケーションよりも速くこれを打つことになります)

それは後のJavasファイナライゼーション/ GCによって、ある種の自動クリーンアップがより効果的に/定期的に行われる可能性があることも示唆されています。あなた自身をきれいに閉じることが最善ですが、以前のJavasでGC/runFinalizationを強制して問題を示してみることもできます。

+0

私はもう一度#2を試してみて、すべてのスレッドが同時に凍っていました。 ページビューのランダム5%です。アプレットが初めて読み込まれたときに発生することがあります。 データストリームをクローズするのを忘れていたので、それが問題でした。しかし、これを行うためのコードを追加しても、問題は解決されませんでした。 だから、私はまだ立ち往生しています。 –

0

私はあなたが直面している問題の原因がわからないんだけど、私は同期アプレット(jarファイルまたはサーバーのいずれかからの負荷)の中から画像をロードするために成功し、次のコードを使用します。

public Image loadImage(String imageName) { 

    // get the image 
    Image image = getImage(getCodeBase(), imageName); 

    // wait for it to fully load 
    MediaTracker tracker = new MediaTracker(this); 
    tracker.addImage(image, 0); 
    boolean interrupted = false; 
    try { 
     tracker.waitForID(0); 
    } catch (InterruptedException e) { 
     interrupted = true; 
    } 

    int status = tracker.statusID(thisImageTrackerID, false); 
    if (status != MediaTracker.COMPLETE) { 
     throw new RuntimeException("Failed to load " + imageName + ", interrupted:" + interrupted + ", status:" + status); 
    } 

    return image; 
} 
関連する問題