java.lang.OutOfMemoryError异常,如果从服务器获取大数据

时间:2015-07-27 04:18:46

标签: java android out-of-memory

我正在使用BufferReader从服务器读取大型json响应,并显示以下错误 -

java.lang.OutOfMemoryError
    at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:156)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:288)
    at java.io.InputStreamReader.read(InputStreamReader.java:233)
    at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
    at java.io.BufferedReader.readChar(BufferedReader.java:263)
    at java.io.BufferedReader.read(BufferedReader.java:253)
    at org.acra.CrashReportData.load(CrashReportData.java:321)
    at org.acra.CrashReportData.load(CrashReportData.java:261)
    at org.acra.ErrorReporter.loadCrashReport(ErrorReporter.java:984)
    at org.acra.ErrorReporter.checkAndSendReports(ErrorReporter.java:959)
    at org.acra.ErrorReporter$ReportsSenderWorker.run(ErrorReporter.java:142)

我使用以下代码从服务器获取数据 - 大字符串数据

public String makeServiceCall(String url, int method,List<NameValuePair> params) {
    try {           
        httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent()
        BufferedReader reader = new BufferedReader(newInputStreamReader(is, "UTF-8"));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        response = sb.toString();           
        //reader.close();
    } catch (Exception e) {
        e.printStackTrace();            
    }
    }
    return response;
} 

5 个答案:

答案 0 :(得分:1)

服务器提供的JSON字符串超过了应用程序堆的预算,并且您将其存储到StringBuilder

不是一个好方法(IMO)。

而不是将其保存到StringBuilder,然后将其作为JSON解析器的源。我建议使用JsonReader。  这样,您就可以直接从InputStream解析JSON。

在您的案例中创建JsonReader对象。

httpEntity = httpResponse.getEntity();
is = httpEntity.getContent()  
JsonReader jsonReader = new JsonReader(new BufferedReader(new InputStreamReader(is, "UTF-8")));

解析过程可以在JsonReader

的文档中找到

答案 1 :(得分:0)

请增加服务器的内存分配大小。 我正在使用JBoss服务器,相应地增加了服务器的内存大小分配。 enter image description here

答案 2 :(得分:0)

处理大量数据时,您可能会遇到以下错误:

  • java.lang.OutOfMemoryError 出现此错误的原因是为JVM配置的堆大小不够,并且这些内存不会留下进一步处理。为了避免此错误,您应首先根据正在处理的数据量来估算堆大小。您可以使用collect设置堆大小的初始值,使用-Xms
  • 设置最大大小
  

java -Xmx2048m -Xms256m

  • java.lang.OutOfMemoryError:PermGen space PermGen空间存储有关JVM加载的类的元数据。如果您一次加载大量类,并且为PermGen空间配置了较小的值,则会收到上述错误。为了避免此错误,请执行有关正在加载和配置空间的类数的估计。您可以使用-Xmx
  • 设置-XX:PermSize和最大值的permGen空间的最小值
  

-XX:PermSize = 512m -XX:MaxPermSize = 512m

答案 3 :(得分:0)

不要一次性阅读文件,而是用块读取文件,例如。

InputStream inputStream= FileInputStream(..);
OutputStream outputStream= new BufferedInputStream(..);
byte buffer[] = new byte[1024*1024];
int read;
while((read = inputStream.read(buffer)) != -1){
    outputStream.write(buffer, 0, read);
}

InputStream inputStream= FileInputStream(..); OutputStream outputStream= new BufferedInputStream(..); byte buffer[] = new byte[1024*1024]; int read; while((read = inputStream.read(buffer)) != -1){ outputStream.write(buffer, 0, read); }

在这里,您将一次读取1 Mb,但可以传输无限量的数据。

答案 4 :(得分:0)

在清单文件的应用程序标记中将largeheap设置为true

<application

    android:largeHeap="true"
     >