天使漫步IT工作室天使漫步IT工作室

android图片相关知识点总结

android 图片相关操作的知识点总结:

  • 1、有一点你必须明确,android在内存中,只会开辟出当前屏幕大小的位图的大小的四倍的空间。
  • 2、举个例子:假如你的手机是854*480的那么像素数是409920,每个像素在内存中占4B,那么就是1639680个字节,乘以4后得到6405KB,那么也就是说所有的Bitmap对象只能占据内存的6405KB空间,当你对Bitmap对象做缩放等等操作时,一定要保证小于当前值。
  • 3、android内存分为native内存和java内存,其中native由图片申请。
  • 4、背景图片可以重复使用,即列表页中生成的图片应该上一个N+1的问题,而不是N+N。
  • 5、resources对象的方法,而resources有两个缓存,第一个是sPreloadedColorDrawables,这里边存的id和drawable的软引用,这个是系统启动时的预加载的资源,另一个是mDrawableCache,这个是应用中用临时加载的资源,同样也是id和drawable的软引用,所以getdrawable速度如此之快,而不占内存。
  • 6、bitmap只是drawable的一个子集。
  • 7、decodeStream 比 decodeResource 快一倍的时间(decodeStream是native方法)。而且,decodeStream会占用更少的内存,加载到500+才会出现oom,而decodeResource则只加载到8张即出现oom。
  • 8、本文想跟大家一起讨论的是另一种情况:明明还有很多内存,但是发生OOM了。
    这种情况经常出现在生成Bitmap的时候。有兴趣的可以试一下,在一个函数里生成一个13m 的int数组。

再该函数结束后,按理说这个int数组应该已经被释放了,或者说可以释放,这个13M的空间应该可以空出来,
这个时候如果你继续生成一个10M的int数组是没有问题的,反而生成一个4M的Bitmap就会跳出OOM。这个就奇怪了,为什么10M的int够空间,反而4M的Bitmap不够呢?

最后,这个问题困扰很久,在网上,国外各大论坛搜索了很久,一般关于OOM的解释和解决方法都是,如何让GC尽快回收的代码风格之类,并没有实际的支出上述情况的根源。

直到昨天在一个老外的blog上终于看到了这方面的解释,我理解后归纳如下:

在Android中:

  • 1.一个进程的内存可以由2个部分组成:java 使用内存 ,C 使用内存 ,这两个内存的和必须小于16M,不然就会出现大家熟悉的OOM,这个就是第一种OOM的情况。
  • 2.更加奇怪的是这个:一旦内存分配给Java后,以后这块内存即使释放后,也只能给Java的使用,这个估计跟java虚拟机里把内存分成好几块进行缓存的原因有关,反正C就别想用到这块的内存了,所以如果Java突然占用了一个大块内存,即使很快释放了。即C能使用的内存 = 16M - Java某一瞬间占用的最大内存。而Bitmap的生成是通过malloc进行内存分配的,占用的是C的内存,这个也就说明了,上述的4MBitmap无法生成的原因,因为在13M被Java用过后,剩下C能用的只有3M了。

本站原创,欢迎转载,转载敬请标明出处:天使漫步IT工作室 » android图片相关知识点总结
添加新评论