Android如何捕获内存溢出,Android 捕获OOM方法

本文不是讲什么时候会发生OOM,而是讲OOM发生了如何去捕获他,处理它

最近在分析Volley通信框架,看到ImageRequest的一段代码,非常值得借鉴

/** Decoding lock so that we don't decode more than one image at a time (to avoid OOM's) */

private static final Object sDecodeLock = new Object();

/** * The real guts of parseNetworkResponse. Broken out for readability. */

@Override

protected Response parseNetworkResponse(NetworkResponse response) {

// Serialize all decode on a global lock to reduce concurrent heap usage.

synchronized (sDecodeLock) {

try {

return doParse(response);

} catch (OutOfMemoryError e) {

VolleyLog.e("Caught OOM for %d byte image, url=%s", response.data.length, getUrl());

return Response.error(new ParseError(e));

}

}

}

private Response doParse(NetworkResponse response) {

......

}

首先使用sDecodeLock同步锁,防止多线程同时解析一张以上图片,可以减少解析图片时发生OOM发生概率

然后捕获Error,注意不是异常,此时如果捕获Exception是无效的,但是可以捕获Throwable,因为Error和Exception都继承自Throwable OutOfMemoryError -VirtualMachineError -Error -Throwable

程序请求分配的内存超过虚拟机分配的内存,那么就会发生OOM

参考:

JVM—内存溢出、OutOfMemoryError、StackOverflowError

摘抄重要的句子

虚拟机栈

栈的作用:栈用于存储局部变量表、操作数栈、动态链接和方法出口等信息.

其中局部变量表用于存放8种基本数据类型(boolean,byte,char,short,int,float,long,double)和reference类型.

reference类型:

- 指向对象起始地址的引用指针

- 指向一个代表对象的句柄

- 指向一条字节码指令的地址

可抛出两种异常状况

线程请求的栈深度大于虚拟机所允许的栈深度,抛出StackOverflowError异常

当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常是

堆的作用:分配所有的对象实例和数组。可以抛出OutOfMemoryError异常。

StackOverflowError

在单线程的堆中我们不断的让一个成员变量自增,容纳这个变量的单元无法承受这个变量了,就抛出StackOverflowError了。

可以开尽量多的线程,并在每个线程里调用native的方法,就自然会抛出 OutOfMemoryError了。

/** * VM Args: - Xss64k *@author Administrator * */

public class JavaVMStackSOF {

private int stackLength = 1;

public void stackLeak(){

stackLength ++;

stackLeak();

}

public static void main(String[] args) throws Throwable {

JavaVMStackSOF oom = new JavaVMStackSOF();

try{

oom.stackLeak();

} catch(Throwable e){

System. out.println("Stack length:" + oom.stackLength);

throw e;

}

}

}

现在终于知道了StackOverflowError和OutOfMemoryError的区别了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值