oom可以被catch 但是没有必要。

正确认识 Error 和 OOM

首先,这里 catch 的是一个 Error,原则上,触发了 Error 时,它的执行状态已经无法恢复了,此时需要终止线程甚至是终止虚拟机。这是一种不应该被我们应用层去捕获的异常。具体可以参见之前的文章《Java 异常捕获》。

然后还要理清楚,OOM 是如何产生的。

其实 OOM 产生的原因有很多,例如申请了大段的内存,虚拟内存不足等等,这些原因都可能引发 OOM。大多数时候,OOM 触发的时候,都只是压死骆驼的最后一根稻草,也许就是正常的内存申请,但是已经没有更多的内存可以使用了,此时就引发 OOM。

例如上面这种 OOM,其实就是开启了一个新页面,在页面的布局中加载了一个本地资源,最终触发 OOM 了。

catch OOM 的先决条件

想通过 try-catch 避免 OOM,你需要两个先决条件:

触发 OOM 的代码是开发者可控的。

在 try 块中,申明对象并会申请了大段内存,导致触发 OOM。

只有满足这两个条件,你才可以说,你对 OOM 有控制权,能够将其 catch 住。

在一些开源库中,其实就已经在使用这种方法。例如 Volley 中,ImageRequest 中,就有这样一段代码。

在处理图片的时候,如果遇见 OOM,就放弃掉,同时把错误抛出去。

应该 catch 住 OOM 吗?

就像前面说过,触发了 Error 时,它的执行状态已经无法恢复了,此时需要终止线程甚至是终止虚拟机。这是一种不应该被我们应用层去捕获的异常。

理论上我们不应该去主动 catch OOM。哪怕在此处 catch 住了,可 App 当前的状态也已经处于“濒危”状态。如果不采取措施,此时不崩,换一个地方也会崩,逃的了初一,逃不过十五。

正确的做法是,主动去管理内存。图片是吃内存的大户,而如果 App 内统一了图片加载库,例如 Glide,在内存吃紧的时候,就可以通过 Glide 主动释放掉一些内存,让 App 恢复到健康的状态。

小结时刻

OOM 能不能被 catch 住?在某些条件下可以。仅在我们可控的代码,并且在 try 块中存在申请大量内存的情况下,此时触发的 OOM,才是可以被 catch 住的。

当我们 catch 住 OOM 的时候,我们应该主动释放一些我们可控的内存,做好内存管理,避免在后续的操作中,立即又会触发 OOM,导致崩溃。

你可能感兴趣的:(oom可以被catch 但是没有必要。)