【问题标题】:'Catching' OutOfMemoryError completely solves out-of-memory issue?'Catching' OutOfMemoryError 完全解决了内存不足的问题?
【发布时间】:2013-06-22 12:56:36
【问题描述】:

我在 LogCat 中收到 OutOfMemoryError 消息,我的应用程序崩溃了,因为这些错误未被捕获。

OutOfMemoryError 有两个原因:
1. 将大文本文件读入字符串。
2. 将该字符串发送到我的 TextView。

简单地在这两件事上添加一个 catch 不仅可以捕获 OutOfMemoryError,而且似乎可以完全解决内存不足的问题。
LogCat 中不再出现崩溃和错误消息。该应用程序运行完美。

这怎么可能?到底发生了什么?


使用此代码,我收到错误消息和应用程序崩溃:

try
{
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next();
} 
catch (FileNotFoundException e) 
{
e.printStackTrace();
}


myTextView.setText(myString);



只需“捕获”OutOfMemoryError,LogCat 中就不会再出现错误消息,也不会崩溃:

try
{
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next();
} 
catch (FileNotFoundException e) 
{
e.printStackTrace();
}
catch(OutOfMemoryError e)
{
}


try 
{
myTextView.setText(myString);
} 
catch(OutOfMemoryError e)
{
}

【问题讨论】:

  • 查看日志在 OutOfMemoryError 捕获块中添加 e.printstacktrace
  • 同意@Droider。您看不到错误消息,因为您没有像以前那样打印它们。

标签: java android try-catch out-of-memory


【解决方案1】:

我猜你的字符串没有完全加载,或者即使它是(它可能会在添加文本后抛出错误),会发生什么取决于你的应用程序可用的当前内存,所以捕获 OutOfMemoryError 不是这是一个可行的解决方案。

如果你真的想加载一个大的字符串文件并将其显示在EditText 中,我建议你只加载文件的一小部分(比如说 50kB),并实现某种分页,比如一个按钮加载下一个 50kB。您还可以在用户滚动EditText 时加载其他行。

【讨论】:

    【解决方案2】:

    如果您捕获 OutOfMemoryError,垃圾收集器会尝试释放之前使用的内存,因此如果应用程序让垃圾收集器完成其工作(即应用程序不再引用该大内存),则应用程序可以继续你的字符串)。

    但是,捕获 OutOfMemoryError 远非万无一失。见Catching java.lang.OutOfMemoryError?

    【讨论】:

      【解决方案3】:

      当您捕获异常时,JVM 会尝试通过调用 垃圾收集器 并抓取不再使用的对象来从中恢复。

      这可能会解决您的问题。但是想象一下,问题是由于代码中的错误编码和内存泄漏而出现的。捕获不会解决问题,因为 GC 不会收集任何对象。 GC 将更频繁地启动,您的应用程序的性能将下降,直到它变得无法使用。

      基本上,当 JVM 无法在堆上为新对象分配更多内存时,就会发生此错误。捕获异常并让 GC 清理和释放内存可能是一种解决方案,但您永远不能绝对确定您处于可恢复状态。我会使用 catch 块从错误中恢复,记录它并关闭应用程序。如果你想解决这种情况下的内存问题,请正确执行并使用更多内存初始化JVM(使用java参数-Xmx

      【讨论】:

      • 我在图像反射方法中遇到了异常。如果发生错误,我可以捕获错误、停止处理、清理对象并简单地使用原始图像吗?
      • 捕获这样的异常确实被认为是一种不好的做法。更好的做法是通过 1) 尝试查找代码泄漏的位置,2) 在程序启动时增加给 JVM 的内存(使用 -Xmx)来避免该异常的发生。另外,我不知道你所说的“图像反射法”是什么意思,你能解释一下吗?
      • 基本上,我从反映图像的现有图像创建一个新图像。抱歉,我想这就是反射。无论如何,代码没有泄漏。使用 Bitmap.createBitmap 创建新图像时,有时会出现错误。如果一切都失败了,我猜我将不得不使用二次采样,但图像已经足够小了。
      • 我最终决定缓存创建的图像,而不是不断地重新创建。谢谢。
      • @frostymarvelous 好!我很高兴能帮上忙。
      猜你喜欢
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多