android开发长时间抓取log报错OutOfMemoryError

img

android开启线程执行Runtime.getRuntime().exec("logcat")去获取android log
线程会不断BufferedReader.readLine,前面抓取log是正常的,当线程一直运行大概2小时会报错

E AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 88 byte allocation with 0 free bytes and 0B until OOM, target footprint 201326592, growth limit 201326592

分析log是BufferedReader.readLine这里的问题,不可以循环去readline?还是需要每读一次readLine就要close掉资源?
帮忙看看代码写的是不是合理的,还有问题的解决办法

循环readLine并不会导致内存溢出;你output方法做了什么

【以下回答由 GPT 生成】

你的怀疑是正确的,问题确实出现在BufferedReader.readLine()这一步。每次调用readLine()方法都会读取一行日志,并存储在内存中,如果持续运行2小时,那么内存中存储的日志数量将非常庞大,导致内存不足。

为了解决这个问题,你可以通过两种方式来优化你的代码。

1. 每次读取后关闭资源

每次调用BufferedReader.readLine()方法后,你需要显式地关闭资源,即调用inputStream.close()bufferedReader.close()方法。这样可以及时释放内存空间。以下是示例代码:

try {
    Process process = Runtime.getRuntime().exec("logcat");
    InputStream inputStream = process.getInputStream();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

    String line;
    while ((line = bufferedReader.readLine()) != null) {
        // 处理日志
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
  try {
    bufferedReader.close();
    inputStream.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

2. 限制日志缓存的大小

另一种解决方法是限制日志的缓存大小,在缓存达到一定大小后,清空缓存。这样可以避免缓存无限增长导致内存不足。以下是示例代码:

try {
    Process process = Runtime.getRuntime().exec("logcat");
    InputStream inputStream = process.getInputStream();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

    String line;
    StringBuilder logStringBuilder = new StringBuilder();
    int logCacheSize = 0;
    while ((line = bufferedReader.readLine()) != null) {
        if (logCacheSize < MAX_CACHE_SIZE) {
            logStringBuilder.append(line).append("\n");
            logCacheSize += line.length();
        } else {
            // 处理日志
            // 清空缓存
            logStringBuilder.setLength(0);
            logCacheSize = 0;
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        bufferedReader.close();
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

请注意,上述代码中的MAX_CACHE_SIZE是一个你需要定义的常量,表示日志缓存的最大大小。你可以根据实际情况调整这个值。

希望以上解决方案能帮助到你。如果还有其他问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^