2013-04-26 60 views
1

林下面的方法来从的WebAPI捕捞数据:OutOfMemoryException异常因使用使用大字符串

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(); 
} 

对于一些要求,这导致由一个太小HEAPSIZE一个OutOfMemoryError异常:

(...)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 (..) 

我已经从正常的字符串操作,如String answer += inputLine交换到一个StringBuilder,但这没有帮助。我怎么解决这个问题?通过export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"增加最大堆大小不是一个选项,因为它是一个Android应用程序。

+0

你想下载什么?它是一个完整的二进制bin文件,xml,json吗? – 2013-04-26 13:36:44

+2

您的应用程序无法缩放,因此无法重写就无法解决问题。当然,你可以添加更多的内存,但它迟早会失败。将内容写入永久存储器(例如文件系统)。如果您真的*知道HTTP资源的最大可能大小,则可以解决此问题。 – home 2013-04-26 13:40:07

回答

2

一个解决办法是坚持内容被下载到storage

根据您下载的内容,您可以在阅读时分析它并将其存储在SQL Lite DataBase中。这将允许您以后使用查询语言处理数据。如果下载的文件是JSON或XML,这将非常有用。

在JSON中,您可以获得InputStream,就像您已经做的一样,并使用JSON Reader读取流。对于从JSON中读取的每条记录,您都可以将其存储在一个表中(或者根据每条记录的结构而有更多的表格)。这种方法的好处在于,最终你不需要文件处理,并且你的数据已经在你的数据库中的表格中分发了,随时可以被查询。

+0

这听起来是一个很好的解决方案,因为它是json – danijoo 2013-04-26 13:49:56

3

将文件用于临时存储,就像当硬盘驱动器由于内存不足而开始分页时一样。

1

您应该将stringbuilder内容写入文件并不时清除它。

1

如果字符串是真的那么大,你需要将其暂时存放在一个文件和块处理它(或块处理它,而你接受它)

0

不是为了胆小鬼,而是编写自己的MyString类,每个char使用一个字节〜50%的内存节省!并且,继续,MyStringBuilder类。只假设你正在处理ASCII。