Bogdan
Bogdan

Reputation: 145

Android StringBuilder out of memory with large XML file

I'm using a soap service on android device and as response I get 7mb file from server. This causes my app to crash with out of memory error when converting input stream to string. MemoryAnalyzer shows that memory was allocated to StreamBuilder. What is the best way to deal with such big responses?

HttpEntity entity = new StringEntity(soap.toString());
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
if( r_entity != null ) {
   result = inputStreamToString(r_entity.getContent());
}
...
//convert stream to string
public static String inputStreamToString(InputStream stream) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(stream));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = br.readLine()) != null) {
          sb.append(line + "\n");
    }
    br.close();
    return sb.toString();
}

Upvotes: 1

Views: 1482

Answers (2)

Audrius Meškauskas
Audrius Meškauskas

Reputation: 21778

StringBuilder requires twice as much memory as it has data at the time of expansion. A new, larger (almost for sure larger than required) array of chars will be allocated and a copy will be made, only then the old array can be discarded.

Collect all lines into ArrayList<String> that is cheaper to grow, just a size of String reference per line. After you finish reading, you can count exact length in a loop and allocate StringBuilder of exactly required size. Close the stream first. Or, maybe you can reuse the list directly without converting into string.

Upvotes: 0

Philippe Girolami
Philippe Girolami

Reputation: 1876

The most obvious answer is to use streams and parse the result as it comes. If it's an XML file you're parsing then SAX is probably the best avenue for you.

Upvotes: 1

Related Questions