OutOfMemoryException caused by large Strings

妖精的绣舞 提交于 2019-12-02 02:21:41

问题


Im using using following Method to catch Data from a webapi:

public static String sendRequest(String requestURL, String data)
        throws IOException {
    URL url = new URL(requestURL + "?" + data);
    URLConnection conn = url.openConnection();
    conn.setReadTimeout(10000);
    BufferedReader in = new BufferedReader(new InputStreamReader(
            conn.getInputStream()));

    String inputLine;
    StringBuilder answerBuilder = new StringBuilder("");
    try {
        while ((inputLine = in.readLine()) != null)
            answerBuilder.append(inputLine);
        in.close();
    } catch (Exception e) {
    }

    return answerBuilder.toString();
}

With some requests, this leads to a OutOfMemoryError caused by a too small HeapSize:

(...)Caused by: java.lang.OutOfMemoryError: (Heap Size=17927KB, Allocated=14191KB, Bitmap Size=2589KB)
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132)
at java.lang.StringBuilder.append(StringBuilder.java:272)
at java.io.BufferedReader.readLine(BufferedReader.java:423)
at com.elophant.utils.HTTPUtils.sendRequest(HTTPUtils.java:23)
at (..)

I already swapped from normal String operations like String answer += inputLine to a StringBuilder but this didnt help. How can i solve this Problem? Increasing maximum heap size via export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m" isnt an option as its an android app.


回答1:


One solution would be to persist the content being downloaded to a storage.

Depending on what you are download you could parse it during its read and store it in a SQL Lite DataBase. This would allow you to use Query language to handle data afterwards. This would be really useful if file being downloaded is a JSON or XML.

In JSON you could get the InputStream as you already do and read stream with the JSON Reader. For every record read from the JSON you can store in a table (or more tables depending on how each record is structured). The good thing from this approach is that at the end you don't need file handling and you already have your data distributed in tables within your database ready to be queried.




回答2:


Use a file for temporary storage like when a hard drive starts paging because it's out of memory.




回答3:


you should write the stringbuilder content into a file and clear it from time to time.




回答4:


If your String is really that large, you will need to store it in a file temporarily and process it in chunks (or handle it in chunks while you receive it)




回答5:


Not for the faint-hearted, but write your own MyString class that uses a byte for each char~ 50% memory savings! And consequnetely, MyStringBuilder class. Only assuming you are dealing with ASCII.



来源:https://stackoverflow.com/questions/16237819/outofmemoryexception-caused-by-large-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!