1 / 21

android 内存管理

android 内存管理. ── 朱鹏. 自我介绍. 朱鹏. Android 开发工程师 qq : 752061935 手机 : 15618953973. 二手房. 租房. 新房. Why. Android 系统有自己的垃圾回收机制,可以自动回收内存空间。那为什么还需要专门做个针对内存管理做一个分享呢? 答案很简单: crash!!!. Bitmap. 谈到 android 内存管理这里不得不提的一个对象就是 Bitmap 。 内存大户

roden
Download Presentation

android 内存管理

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. android内存管理 ──朱鹏

  2. 自我介绍 朱鹏 Android开发工程师 qq : 752061935 手机 : 15618953973 二手房 租房 新房

  3. Why Android系统有自己的垃圾回收机制,可以自动回收内存空间。那为什么还需要专门做个针对内存管理做一个分享呢? 答案很简单: crash!!!

  4. Bitmap 谈到android内存管理这里不得不提的一个对象就是Bitmap。 内存大户 而一个andriod程序运行过程中所占用的内存(native+dalvik)超过>16M(默认) OOM

  5. 查看内存使用情况 adb shell dumpsys meminfo $package_name or $pid

  6. Bitmap对象 bitmap对象 linux底层C内存 android虚拟机 (DVM)

  7. recycle() 首先明确一点无论你调用不调用recycle()方法,android程序都不会内存泄露。 recycle只做了一件事:The bitmap is marked as 'dead'。 recycle真的用途在于:它可以帮助GC快速决定是否回收这个对象,当一个应用包含大量的图片的时候,这个方法还是很有作用的,因为GC并没有你想象的聪明。

  8. recycle()具体使用 // 先判断是否已经回收 if(bitmap != null && !bitmap.isRecycled()){ // 回收并且置为null bitmap.recycle(); bitmap = null; }

  9. 这里再介绍一个比较实用的方法 if(imageView != null && imageView.getDrawable() != null){ Bitmap oldBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); imageView.setImageDrawable(null); if(oldBitmap != null){ oldBitmap.recycle(); } }

  10. 建议在一个大量使用图片的应用中activity继承以下BaseActivity建议在一个大量使用图片的应用中activity继承以下BaseActivity public class BaseActivity{ ArrayList<SoftReference<Bitmap>> bitmapCache = new ArrayList<SoftReference<Bitmap>>(); @Override protected void onDestroy() { for(SoftReference<Bitmap> sb:bitmapCache ){ 回收操作 } super.onDestroy(); } }

  11. bitmap什么时候会导致程序OOM 单张图片过大 解决方案: 1、调整dvm单个堆栈大小 2、压缩图片 3、切割图片 小图片累积过多 解决方案: 1、用完即手动recycle

  12. 图片压缩小技巧 在使用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:原理其实就是通过图片的头部信息读取图片的基本信息)

  13. Bitmap在listview和gallery中的典型使用 Map<String, SoftReference<Bitmap>> mBitmapList ; public void loadImage(imageView,url){ 1、根据url从内存即mBitmapList 读取地图,如果内存没有读到图片则进行第二步。 2、根据url读取本地图片,如果没有读取到,则进行第三步。 3、将url加入下载队列,下载成功后将bitmap加入内存缓存即mBitmapList 。 } ps:在listview和gallery滑动的过程中可以不断手动recycle()不用的bitmap对象,维持内存缓存mBitmapList 固定大小,这样可以减小oom发生的概率。

  14. gallery的问题 经过以上处理之后你会发现listview很好用了,很难在发生OOM。但是你会发现一个问题,这种方法在gallery上总是不好用,要不是出现OOM,就是抛出异常try to recycle a using bitmap。 这是为什么呢?

  15. 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; } }

  16. 原因分析 Gallery:没有实现convertView的复用。 if(convertView==null){...永远进入这段代码执行...} 这点值得所有android开发工程师注意,一不小心就掉入陷阱里面了。

  17. "软引用失效" 软引用 hashmap bitmap imageview 强引用 因为gallery本身没有实现view的复用导致程序会new很多个imageview,而只有当imageview被释放的时候和他绑定bitmap才有可能被释放。当你强行通过recycle释放bitmap时,就会导致try to recycle a using bitmap异常。

  18. gallery推荐使用以下代码 private ArrayList<ImageView> mImageViewList = new ArrayList<MyImageView>(); 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复用的目的。

  19. 再次强调 禁止出现占据大块内存的不能释放的引用,尤其是静态引用特别注意,特别有些同学喜欢把某个activity的context赋值某个静态变量,直接导致这个activity的生命周期延长至整个程序期间,占据大量内存。 使用bitmap软引用自动释放的时候,要确保引用该bitmap的view能及时释放,这样bitmap才有机会被释放,最好采用手动recycle方式。

  20. Thanks

More Related