Android内存管理


android内存管理 ── 朱鹏 自我介绍 朱鹏 Android开发工程师 qq : 752061935 手机 : 15618953973 二手房 租房 新房 Why •  Android系统有自己的垃圾回收机制,可以自动回收 内存空间。那为什么还需要专门做个针对内存管理做 一个分享呢? •  答案很简单: crash!!! Bitmap 谈到android内存管理这里不得不提的一个对象就是 Bitmap。 •  内存大户 •  而一个andriod程序运行过程中所占用的内存(native +dalvik)超过>16M(默认) OOM 查看内存使用情况 adb shell dumpsys meminfo $package_name or $pid Bitmap对象 bitmap对象 android虚拟机 (DVM) linux底层C内存 recycle() •  首先明确一点无论你调用不调用recycle()方法, android程序都不会内存泄露。 •  recycle只做了一件事:The bitmap is marked as 'dead'。 •  recycle真的用途在于:它可以帮助GC快速决定是否 回收这个对象,当一个应用包含大量的图片的时候, 这个方法还是很有作用的,因为GC并没有你想象的 聪明。 recycle()具体使用 // 先判断是否已经回收 if(bitmap != null && !bitmap.isRecycled()){ // 回收并且置为null bitmap.recycle(); bitmap = null; } 这里再介绍一个比较实用的方法 if(imageView != null && imageView.getDrawable() ! = null){ Bitmap oldBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); imageView.setImageDrawable(null); if(oldBitmap != null){ oldBitmap.recycle(); } } 建议在一个大量使用图片的应用中activity继承以下BaseActivity public class BaseActivity{ ArrayList> bitmapCache = new ArrayList>(); @Override protected void onDestroy() { for(SoftReference sb:bitmapCache ){ 回收操作 } super.onDestroy(); } } bitmap什么时候会导致程序OOM •  单张图片过大 解决方案: 1、调整dvm单个堆栈大小 2、压缩图片 3、切割图片 •  小图片累积过多 解决方案: 1、用完即手动recycle 图片压缩小技巧 •  在使用BitmapFactory压缩图片的时候, BitmapFactory.Options设置inJustDecodeBounds 为true后,再使用decodeFile()等方法,可以在不分 配空间状态下计算出图片的大小。示例: BitmapFactory.Options opts = new BitmapFactory.Options(); // 设置inJustDecodeBounds为true opts.inJustDecodeBounds = true; // 使用decodeFile方法得到图片的宽和高 BitmapFactory.decodeFile(path, opts); // 打印出图片的宽和高 Log.d("example", opts.outWidth + "," + opts.outHeight); (ps:原理其实就是通过图片的头部信息读取图片的基本信息) Bitmap在listview和gallery中的典型使用 Map> mBitmapList ; public void loadImage(imageView,url){ 1、根据url从内存即mBitmapList 读取地图,如果内存没有 读到图片则进行第二步。 2、根据url读取本地图片,如果没有读取到,则进行第三 步。 3、将url加入下载队列,下载成功后将bitmap加入内存缓 存即mBitmapList 。 } ps:在listview和gallery滑动的过程中可以不断手动recycle() 不用的bitmap对象,维持内存缓存mBitmapList 固定大 小,这样可以减小oom发生的概率。 gallery的问题 •  经过以上处理之后你会发现listview很好用了,很难 在发生OOM。但是你会发现一个问题,这种方法在 gallery上总是不好用,要不是出现OOM,就是抛出 异常try to recycle a using bitmap。 •  这是为什么呢? gallery相关的adapter的常见写法 class GalleryAdapter extends BaseAdapter{ public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ holder = new ViewHolder(); holder.photo = new Imageview(); convertView.setTag(holder ); }else{ holder = (ViewHolder) convertView.getTag(); } return holder.photo; } } 原因分析 •  Gallery:没有实现convertView的复用。 if(convertView==null){...永远进入这段代码执行...} •  这点值得所有android开发工程师注意,一不小心就 掉入陷阱里面了。 "软引用失效" •  因为gallery本身没有实现view的复用导致程序会new很 多个imageview,而只有当imageview被释放的时候和他 绑定bitmap才有可能被释放。当你强行通过recycle释放 bitmap时,就会导致try to recycle a using bitmap异常。 hashmap imageview bitmap 软引用 强引用 gallery推荐使用以下代码 private ArrayList mImageViewList = new ArrayList(); public View getView(int position, View convertView, ViewGroup parent) { if(mImageViewList.get(nowPosition) == null){ imageView = new MyImageView(mContext); mImageViewList.set(nowPosition, imageView); } else { imageView = (MyImageView) mImageViewList.get(position % mImageViewList.size()); } return imageView; } 通过使用ArrayList达到imageView复用的目的。 再次强调 •  禁止出现占据大块内存的不能释放的引用,尤其是静 态引用特别注意,特别有些同学喜欢把某个activity 的context赋值某个静态变量,直接导致这个activity 的生命周期延长至整个程序期间,占据大量内存。 •  使用bitmap软引用自动释放的时候,要确保引用该 bitmap的view能及时释放,这样bitmap才有机会被 释放,最好采用手动recycle方式。 Thanks
还剩20页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

sheng5200

贡献于2013-07-01

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf