2016-09-16 6 views
1

私の外部サーバにHttpリクエストを送信して、サイズが100MBの.txtファイルをダウンロードする簡単なコードがあります。 40メガバイトのような小さなファイルは機能していますが、大きなものにはいくつかの問題があります。LibGDXネットでAndroid上に100MBのファイルをダウンロードできません

Net.HttpRequest request = new Net.HttpRequest(Net.HttpMethods.GET); 
    request.setTimeOut(2500); 
    String assetsUrl = "http://111.111.111.111/100mb.txt"; 
    request.setUrl(assetsUrl); 


    // Send the request, listen for the response 
    // Asynchronously 
    Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() { 
     @Override 
     public void handleHttpResponse (Net.HttpResponse httpResponse) { 


      InputStream is = httpResponse.getResultAsStream(); 
      OutputStream os = Gdx.files.local("100mb.txt").write(false); 

      byte[] bytes = new byte[1024]; 
      int count = -1; 

      try { 

       while ((count = is.read(bytes, 0, bytes.length)) != -1) { 
        os.write(bytes, 0, count); 
       } 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 


     } 

進捗状況を表示するコードがいくつかありますが、ここでは重要ではありません。 問題は、ファイルのサイズが100MBであるということですが、Androidは魔法のようにそれをダウンロードしながら400メガバイト+ RAMを割り当て、エラーが付属しています:

Waiting for a blocking GC Alloc

WaitForGcToComplete blocked for 12.906ms for cause Alloc

Starting a blocking GC Alloc

Starting a blocking GC Alloc

Suspending all threads took: 35.332ms

Alloc partial concurrent mark sweep GC freed 214(21KB) AllocSpace objects, 1(200MB) LOS objects, 6% free, 216MB/232MB, paused 1.076ms total 130.115ms

Suspending all threads took: 205.400ms

Background sticky concurrent mark sweep GC freed 364(10KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 416MB/416MB, paused 10.448ms total 304.325ms

Starting a blocking GC Alloc Starting a blocking GC Alloc

Alloc partial concurrent mark sweep GC freed 113(3KB) AllocSpace objects, 0(0B) LOS objects, 3% free, 416MB/432MB, paused 290us total 17.611ms

Starting a blocking GC Alloc

Alloc sticky concurrent mark sweep GC freed 31(912B) AllocSpace objects, 0(0B) LOS objects, 3% free, 416MB/432MB, paused 268us total 6.474ms

Starting a blocking GC Alloc

Alloc concurrent mark sweep GC freed 43(13KB) AllocSpace objects, 0(0B) LOS objects, 3% free, 415MB/431MB, paused 268us total 15.008ms

Forcing collection of SoftReferences for 300MB allocation

Starting a blocking GC Alloc

Alloc concurrent mark sweep GC freed 42(1256B) AllocSpace objects, 0(0B) LOS objects, 3% free, 415MB/431MB, paused 286us total 12.426ms

Throwing OutOfMemoryError "Failed to allocate a 314572860 byte allocation with 16770608 free bytes and 96MB until OOM"

私はダウンロードプロセスを実行すると、私は私が1ギガバイト割り当てられている私のデバイス上で見ることができます(システムによる)と600メガバイトフリーの間、アプリは20-30メガバイトを使用しています。数秒後、私のアプリはますます多くのメモリを割り当て始め、400MB以上を使用していることがわかります。ログに記録されているように、最大​​値に達するとクラッシュが発生します。

おそらく私はそれを理解していないかもしれませんが、それはデータのチャンクを格納するために必要な100MBのRAMだけを割り当てるべきではありませんか? 私はほぼ100%が私のアプリに漏れがないことを確信しています - メモリはダウンロードプロセスによって消費されています。

答えて

1

私はLibGDX、特にgetResultAsStringを見ました。最終的にあなたが

public static String copyStreamToString (InputStream input, int estimatedSize, String charset) throws IOException { 
     InputStreamReader reader = charset == null ? new InputStreamReader(input) : new InputStreamReader(input, charset); 
     StringWriter writer = new StringWriter(Math.max(0, estimatedSize)); 
     char[] buffer = new char[DEFAULT_BUFFER_SIZE]; 
     int charsRead; 
     while ((charsRead = reader.read(buffer)) != -1) { 
      writer.write(buffer, 0, charsRead); 
     } 
     return writer.toString(); 
    } 

をcom.badlogic.gdx.utils.StreamUtils.copyStreamToString に取り掛かるこれはひどい見えませんが、私の推測では、何か内部配列の繰り返し再配分を引き起こすにStringWriterで起こっているのです。 this answerを見ると疑いがあるようです。

StringWriter writes to a StringBuffer internally. A StringBuffer is basically a wrapper round a char array. That array has a certain capacity. When that capacity is insufficient, StringBuffer will allocate a new larger char array and copy the contents of the previous one. At the end you call toString() on the StringWriter, which will again copy the contents of the char array into the char array of the resulting String.

つまり、ファイルをダウンロードする別の方法があるはずです。 This questionには、より堅牢なソリューションがいくつかあります。

関連する問題