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<Bitmap> 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<Bitmap> doParse(NetworkResponse response) {
        ......
    }
  1. 首先使用sDecodeLock同步锁,防止多线程同时解析一张以上图片,可以减少解析图片时发生OOM发生概率
  2. 然后捕获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、付费专栏及课程。

余额充值