0

重複の可能性:
大きな JSON (InputStream) を文字列に配置する際のメモリ不足エラー

HttpResponse 経由でエンコードされた JSON 文字列を取得しています。コードは次のようになります。

    BasicResponseHandler brh = new BasicResponseHandler(); 
    String responseString = brh.handleResponse(response); 
    String decoded = new String(Base64.decode(responseString, Base64.NO_CLOSE));

次のようなエラーが表示されます。

09-03 12:57:09.664: E/AndroidRuntime(8309): FATAL EXCEPTION: Thread-272
09-03 12:57:09.664: E/AndroidRuntime(8309): java.lang.OutOfMemoryError
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.CharArrayBuffer.<init>(CharArrayBuffer.java:43)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.ReadWriteCharArrayBuffer.<init>(ReadWriteCharArrayBuffer.java:47)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.CharBuffer.allocate(CharBuffer.java:54)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.CharsetDecoder.allocateMore(CharsetDecoder.java:236)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:195)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.Charset.decode(Charset.java:487)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.lang.String.<init>(String.java:174)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.lang.String.<init>(String.java:141)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at xxx.DataManager.doPost(DataManager.java:448)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at xxx.DataManager.run(DataManager.java:185)

時々私はそれを手に入れます

brh.handleResponse(response); 

時々オン

String decoded = new String(Base64.decode(responseString, Base64.NO_CLOSE));

したがって、文字列が大きすぎて処理できないと思います(サイズをバイト単位で決定する方法がわかりません)。これを回避するにはどうすればよいですか?

4

1 に答える 1

1

最終的な JSON データ構造のみが完全にメモリに保持されるストリーミング アプローチに切り替える必要があります。他の部分、特に JSON でエンコードされた HTTP 応答は、チャンクごとに処理されます。そのため、最小限のメモリしか必要としません。

そうすれば、いくつかの利点があります。

  • 全体的なメモリ消費量が大幅に削減されます。

  • (大きな文字列の場合と同様に) 大きな割り当ての数が大幅に削減されます。(使用可能な十分なメモリがある場合もありますが、大きな文字列を割り当てるのに十分な大きさのピースが 1 つもありません。)

  • 応答からの最初のバイトが到着するとすぐに解析を開始できるため、解析はデータ受信と並行して実行できます。したがって、アプリは高速になります。

org.json.JSONObjectストリーミングをサポートしていません。代わりに別のクラスを使用する必要があります。

ところで: Base 64 で JSON データをエンコードする理由はわかりません。JSON はテキスト ベースの形式ですが、バイナリ データが関与する場合は Base 64 エンコーディングが必要です。

于 2012-09-03T13:18:45.587 に答える