将大型 JSON(输入流)放入字符串时出现内存不足错误

2022-09-03 02:50:47

我从Web服务收到gziped JSON,然后解压缩它(解压缩JSON的大小为3.2MB)。我需要将收到的输入流转换为字符串,以便我可以创建JSONObject并解析它。我用这个代码来做:

public static String InputStreamToString(InputStream in) 
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();

    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }        
    return buf.toString();
}

我在最后一行收到java.lang.OutOfMemoryError:“返回buf.toString();”在模拟器和设备上具有288MB Ram。

我该怎么办?


答案 1

一次读取一个字节1990年代。要么使用 HttpClient 和 ,要么至少读取可观块中的数据,并使用 .BasicResponseHandlerStringBuilder

假设你仍然遇到问题,问题是,根据你的应用一直在执行的其他事情,没有一个足以容纳你的字符串的内存块。Android 垃圾回收器不是压缩收集器,因此可能有大量的可用堆空间,但不足以满足特定的分配请求。

在这种情况下,您可能需要切换到某种流式处理 JSON 解析器。如果您碰巧只针对Honeycomb及更高版本,则可以使用JSONReader。否则,据报道,杰克逊在Android上工作,并且显然具有流媒体模式。


答案 2

您可以尝试使用以下命令创建新的 JSON 对象

new JSONObject(new JSONTokener(in)) 

而不是直接转换为字符串。但是,这可能只会延迟问题。如果您没有足够的内存将 3.2 meg 字符串加载到内存中,则可能没有足够的内存将其作为 json 对象加载,这将比简单字符串占用更多的内存。