用bitmap.recycle,并不是那么的straightforward

当你的项目中用到了大量了bitmap/drawable,那么你必须要时刻的关注着OOM(out of memory)
在android中,这两个东东最耗内存

你可以使用weakreference/softreference,或者,自己设计的缓存机制来解决OOM

但是,无可避免的,当你感觉到你的解决已经近乎完美的时候,你会时不时的遇见OOM,然后,你又实验了一次,没有遇到,然后,10次之后,你又遇到了

你会重新检查你的代码,但是按照你当前的知识理解,你暂时找不到漏洞

*************************************

bitmap的释放:bitmap.recycle
drawable的释放:drawable.setcallback(null),或者,你知道你的drawable是一个bitmapdrawable,那么bitmapdrawable.getbitmap().recycle
drawable.setcallback(null)这一条往往和context相关,详情参见:
http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html

*************************************

recycle,你释放掉了没?
Free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as "dead", meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing. This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
可以知道:它和system.gc一样,都只是我们的一厢情愿,且android并不鼓励我们去做,因为:

如果你使用了recycle,接下来,你将发现一些诡异的现象,比如:
我有20张图片,我加载了第2张(采用resource.getdrawable),我使用了第2张,接下来,我recycle了第2张。该过程是正常的
过了一段时间,我又重新构建了第2张(采用resource.getdrawable),我使用了第2张,我发现了异常:“引用了一个被recycled的bitmap”
很诡异吧,我重新构建了一个新的对象(至少,看上去是两次resource.getdrawable调用),然后它告诉我,那个对象被recycle了

这个问题,也很好解决:请使用bitmapfactory.decodeResource来构建对象

 

*************************************

既然recycle并不立刻清除垃圾,而我们为什么要调用
因为android app的被分配的内存有限
且,bitmap被我们设置成垃圾后,android/java并没有及时的为我们清理

*************************************

一些比较好的资源,来介绍如何避免OOM
http://labs.ywlx.net/?p=1689
http://lp43.blogspot.com
中11年11月的article

猜你喜欢

转载自baosu.iteye.com/blog/1840057