【问题标题】:InputStream and OutOfMemory ErrorInputStream 和 OutOfMemory 错误
【发布时间】:2016-11-26 12:36:52
【问题描述】:
public String loadJSONFromAsset(String path) {
    String json = null;
    try {
        InputStream is = this.getAssets().open(path);
        int size = is.available();
        Log.d("Size: ", "" +size);
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        json = new String(buffer, "UTF-8");
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return json;
}

这是将文件转换为 JSON 数据文件的代码。它从字面上工作,它创建 JSON 文件,但“is”的大小是 appr。 8MB

D/Size:: 7827533

并且OutOfMemory 错误发生在大多数设备上,例如

java.lang.OutOfMemoryError
at java.lang.String.<init>(String.java:255)
at java.lang.String.<init>(String.java:228)
at com.example.fkn.projecttr.List.loadJSONFromAsset(List.java:255)

我该如何处理?如何编码更有效?它运行时间没有问题,但它在设备上消耗了太大的内存。因此,当设备内存没有更多容量时,程序就会崩溃。

【问题讨论】:

  • 与您的问题无关,但不要在catch 块中使用return
  • 感谢您的建议!
  • 由于您在此处执行的操作,这可能不会发生:在其他代码中创建的对象可能会占用您的大部分可用内存。
  • 在AndroidManifest应用标签中添加android:largeHeap="true"
  • @bradimus 是因为样式原因还是从 catch 块返回有一些风险?

标签: java android json out-of-memory inputstream


【解决方案1】:

我注意到了这一点:

    int size = is.available();

觉得有点奇怪。所以我去看了the JavaDoc for InputStream.available,这就是它要说的:

请注意,虽然 InputStream 的某些实现会返回流中的总字节数,但很多不会。使用该方法的返回值来分配一个用于保存该流中所有数据的缓冲区是不正确的。

所以你有两个条件之一:

  1. 您的文件大小实际上是 8MB。

    如果您真的有这么多 JSON,您需要重新考虑其中的内容以及使用它的目的。我没有看到很多开发人员使用的一个选项是JsonReader,它允许您解析 JSON,而无需先将整个流加载到内存中。

  2. 您的文件大小远小于 8MB

    只是以不同的方式读取文件,见How do I create a Java string from the contents of a file?

【讨论】:

    【解决方案2】:

    保持字节压缩,ByteArrayOutputStream 上的 GZipOutputStream(或 gzip 压缩资产)。

    然后总是使用 GZipInputStream 处理它,用于输出、解析或其他任何事情。

    这至少会安全 20 倍(10 倍压缩,约 3 倍的开销)。

    对于侵入性较小的更改(以及更多的内存消耗):现在有一个 8 MB 字节数组和一个 16 MB 字符串。字符串可以立即解析为 DOM,因此 JSON。丢弃空格,并且相等的字符串值映射到一个字符串实例(例如通过Map&lt;String, String&gt; idmap)。这取决于数据中是否有很多重复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2016-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多