9

AWS の Web サービスから大量のコンテンツをダウンロードする複雑なアプリがあります。ただし、SocketTimeoutException50% の確率で取得し続けます。私の調査に基づいて、次の理由があると思われます。

  • 接続タイムアウトの時間が短縮されました: 100 秒に増やしましたが、それでもこのエラーが発生し続けます。
  • メモリ リーク:GC警告が表示され続けます。記事を読んでコードを改善しようとしましたが、どちらも役に立ちません。また、私のアプリは 2000 個以上の 30KB の JSON ファイルをバックグラウンド スレッドで次々とダウンロードすることにも言及する必要があります。これを効率的に即興するための提案は大歓迎です!
  • サーバーの問題: Amazon Web Service は信頼性が高いため、根本的な問題ではない可能性があります。
  • 複数のスレッド:これはどういうわけか責任がありますか?
  • 誤ったダウンロード方法: ダウンロード方法が非効率的ではないかと疑っています。私が間違っている場合は修正してください。

本当の問題を理解するのを手伝ってください。ありがとう !

public synchronized String getJSONString(String url)
{   
    try {
           URL url1 = new URL(url);
           URLConnection tc = url1.openConnection();
           tc.setConnectTimeout(timeout);
           tc.setReadTimeout(timeout);
          // tc.connect();
           br = new BufferedReader((new InputStreamReader(tc.getInputStream())),8000);
           while ((line = br.readLine()) != null) {
                    sb.append(line+"\n");
                }
                br.close();
                json = sb.toString();
                return json;
        }
    catch(Exception e)
    {
        Log.e("JSON Downloader", "Error downloading feed/article ");
        e.printStackTrace();
    }

    return null;
}

エラーログ:

02-01 06:37:43.375: W/System.err(5548): java.net.SocketTimeoutException
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491)
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
02-01 06:37:43.375: W/System.err(5548):     at java.io.InputStream.read(InputStream.java:163)
02-01 06:37:43.375: W/System.err(5548):     at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
02-01 06:37:43.375: W/System.err(5548):     at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
02-01 06:37:43.375: W/System.err(5548):     at libcore.io.Streams.readAsciiLine(Streams.java:201)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:544)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:784)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
02-01 06:37:43.375: W/System.err(5548):     at com.in.feeds.JSONDownloader.getJSONString(JSONDownloader.java:65)
02-01 06:37:43.375: W/System.err(5548):     at com.in.feeds.JSONDownloader.getJSONObjectFromUrl(JSONDownloader.java:45)
02-01 06:37:43.375: W/System.err(5548):     at com.in.fullarticle.ArticlePage$LoadArticle.run(ArticlePage.java:383)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-01 06:37:43.375: W/System.err(5548):     at java.lang.Thread.run(Thread.java:856)
4

1 に答える 1

1

私はこれに取り組んでいますが、パフォーマンスを探すときに読むことをお勧めする記事が 1 つあります: http://www.kegel.com/java/wp-javaio.html

接続タイムアウトはサーバー側で発生する可能性があります。Web サーバーに接続していると仮定して、そこで受信したエラーを確認してください。

GC ステートメントは驚くべきことではありません。これはメモリ リークではなく、Java のクリーンアップです。上記記事より:

まず、while ループの最初の行を見ると、読み取られるファイルのすべての行に対して新しい String オブジェクトが作成されていることがわかります。

while ((line = in.readLine()) != null) {

これは、たとえば、100,000 行のファイルの場合、100,000 個の String オブジェクトが作成されることを意味します。多数のオブジェクトを作成すると、オブジェクトにスペースを割り当てる時間とメモリ、オブジェクトを初期化する時間、オブジェクトをガベージ コレクションする時間の 3 つの方法でコストが発生します。

マルチスレッドに関しては、もう少しコードを提供する必要があります。メソッドは同期されているため、少なくとも同じインスタンスで同時に複数の呼び出しを回避できます。NWコードは、一目で安全です。

私のデバッグ戦略は、入力行を受け取ったときにサーバー側の最初と 2 番目のストアのタイムスタンプを調べて、ギャップが発生していないか (送信エラー) を確認することです。

幸運を

于 2013-02-04T20:28:46.547 に答える