Android OOM以及让GC尽快回收的代码风格

        有时候会遇到这样一种情况,假设最大使用memory是16m,然后我们在一个函数中new一个14m的int数组,执行完这个

函数之后这个int数组按理应该被释放了或者说可以被回收了,这时候我们再new一个14m的数组不会报错,但是如果我们生成

一个4m的bitmap就是报OOM错误,这是为何呢?

参考了一些资料后总结如下:

可能会有人说Maximum是由java占用的内存空间和c占用的内存空间组成,bitmap是分配到c占用的内存空间,

c的内存空间= maximum - java占用的内存空间,正是因为java占用太多的内存空间才会导致c的内存空间不足

但是native heap size = 1595085KB要远远超过Dalvik VM heapSize,所以以上观点是不正确的,那么上述情况

为什么会报OOM呢?查看源码:

 jobjectGraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,  boolisMutable, jbyteArray ninepatch, int density)
    {
        SkASSERT(bitmap);
        SkASSERT(bitmap->pixelRef());

        jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
                static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)),
                buffer, isMutable, ninepatch,density);
        hasException(env); // For the side effectof logging. 
        return obj;
    }

可以看到bitmap对象是env->NewObject()方法创建的,bitmap对象是由虚拟机创建的,NewObject()返回的是java对象,并不是native对象,

所以bitmap是分配到虚拟机内存的。至于为什么会OOM我猜是因为bitmap在创建的时候利用了native的内存空间,然后再把其分配到虚拟机

bitmap在创建的时候并没有触发GC去回收空内存!

下面是一个老外的博文,虽然可能有些结论不大正确,但是还是可以借鉴:

> You might try to pre-allocate bitmap memory before launching the WebViews?It's not the WebView that's triggering the OOM,

but some arbitrary other piece of code that needs memory that is not *there* anymore. Very often this is happening when starting

a new activity.

            Ok, I see, I have to start dealing with automating my apology.There is one more, small thing that I can do. I also do some

downloading and XML parsing in the background at times. This only takes Java Heap (<3MB),but maybe I should move that stuff

to a separate process. This may lower thechances of an OOM. I'll think about it, but with all the added complexity ofinter process

communication I am not sure I would want to go there.
    > I think it's better to add a couple more columns to the table to see the picture (as I see it) more clearly:

    > JH = Java Heap
    > JU = Memory actually used by Java
    > NH = Native Heap
    > TU = Total memory Used = JU + NH
    > TA = Total memory Allocated = JH + NH
    >
            > (note I'm not distinguishing between native heap and native heap used because it's not relevant here)
            >
            > The system requires TA (the process size as you called it) to not exceed 16MB, the evolution is:
            >
            >   JU JH NH TU TA
            > 1) 2   2    0    2   2
            > 2) 4   4    0    4   4
            > 3) 4   4    2    6   6
            > 4) 14 14  2   16 16
            > 5) 4   14  2    6   16
            > 6) 4   14  4   10  18 *** OH NO! ***
            >
            > The key is what happens between (4) and (5): GC reclaims 10MB (JU reduced> by 10MB) but the java heap

            doesn't shrink (JH stays at 14MB). This enlarged > java heap basically squeezes the maximum native heap allocation.

              the above conclusion mabe not collect ,i thank it was because of the creation of bitmap did not invoke the GC to reclaim the garbage memmory 
            >
            > The simplest approach is to try and ensure that your application maintains
            > a 'flatish' memory profile - no big spikes. You should do this anyway, since
            > it means that your application is being well behaved and won't force other
            > apps to be terminated just because your application needs a temporary shot> of memory (which will then remain as a glut until the application restarts).
            >
            > As you point out, WebViews are heavy on memory usage, and these might be
            > what's causing your memory usage to spike. I don't have any good suggestions
            > for a fix. You might try to pre-allocate bitmap memory before launching the
            > WebViews? It might work, but it may be complicated to do and could cause
            > OOMs when WebViews are instantiated - no way around that, your application
            > is simply using too much memory at that point.
            >

便于GC回收的代码风格:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值