2

一度に複数のJson文字列[各1MB]をPHPサーバーに送信しようとしています。10レコードを送信しようとすると、正常に機能します。ただし、20レコードを超える場合は、と表示されますOutOfMemoryException。私はAndroidのメモリサイズ制限t015MB-16MBを見ました。しかし、これを解決する方法の手がかりはありません。私は以下のコードを使用して、一度に複数のレコードを送信しています。

 /** Upload Data*/
private void submitUploadData(String url, Map<String, String> param)
        throws IOException {
    URL siteUrl;
    try {
        siteUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) siteUrl
                .openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setDoInput(true);

        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        String content1 = ""; 

        Set getkey = param.keySet();
        Iterator keyIter = getkey.iterator();
        String content = "";
        for (int i = 0; keyIter.hasNext(); i++) {
            Object key = keyIter.next();
            if (i != 0) {
                content += "&"; //Crashing here
            }
            content += key + "=" + param.get(key); //Crashing here
            System.out.println("Content" + content);
        }

        System.out.println(content);
        out.writeBytes(content.trim());
        out.flush();
        out.close();

        BufferedReader in = new BufferedReader(new InputStreamReader(
                conn.getInputStream()));
        String jsonresponse = "";
        while ((jsonresponse = in.readLine()) != null) {
            System.out.println(jsonresponse);   
            if(!jsonresponse.equals("Authorisation Successful")){
            updateUploadRecords(jsonresponse);}

        }
        in.close();  

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } 
}
4

4 に答える 4

4

一見したところ、コードに問題はありませんが、メモリの浪費であることが知られている可能なすべてのタイプのメソッドを使用しており、メモリを使い果たしている大規模な操作を試みているため、それが発生することが保証されていました。

チップ:

  • str1 += str2 + "other val"メモリ内に 3 つの新しい文字列を作成したばかりの文字列を連結しないでください。代わりに StringBuilder を使用してください。
  • System.gc() を呼び出す (一部の人が提案するように) は役に立ちません。なぜなら、この操作を実行しているループ内にあり、そのメソッドは GC に適した時期である可能性があることをシステムに示唆するだけですが、システムが実際にあなたはすでにクラッシュしているでしょう。
  • 各 JSON 文字列が約 1 MB で、そのうちの 20 個を渡している場合、古いデバイスでは 20 MB のメモリ不足で既にクラッシュしています。かなりの数を再設計する必要がありますが、私の提案は、マップを完全に削除することです。

代わりに、(そのマップを作成しているメソッドで)何らかのタイプを使用OutputStreamして、一時ファイルに既にフォーマットされているすべてのデータを書き込む必要があります。次に、アップロードするには、ある種の を使用InputStreamしてこのファイルから読み取り、DataOutputStream

ストリームに代わるものは、ストリームと同じ方法論に基づく他のクラスを使用することです。それらは JsonWriter/JsonReader ですが、渡しているものが特定の Json でない場合は FileWriter/FileReader もあります。忘れないでください。それらを常に BufferedReader と BufferedWriter でラップします。

于 2013-03-06T10:11:19.597 に答える
0

たぶんそれはあなたの仮想デバイスのメモリサイズによって制限されます!?

より大きなメモリを与えて試してみましたか!?

于 2013-03-06T09:41:29.720 に答える
0

あなたはそれをオブジェクトで繰り返しています。彼らがコピーを保持するなどのリスクがあります...基本に戻って関数を使用してからString.split('');、通常のループで繰り返します。次に、どのオブジェクトがメモリ内にあるかがわかります。分割を行うと、元の文字列と分割の結果の配列という 2 つのメモリを大量に消費するオブジェクトが得られます。

元の文字列を分割した時点で、元の文字列を に設定しnullて、ガベージ コレクター用のメモリを解放できます (おそらく を呼び出しますSystem.gc()) 。

次に、フットプリントをできるだけ小さく保ちながら、操作ごとに操作を行う文字列を単純にループします。

于 2013-03-06T09:46:03.140 に答える