android_Android操作系统的内存回收机制




  Android操作系统的内存回收机制:
  特殊的资源管理机制原因在于其设计之初就是面向移动终端,退出但不关闭;回收动作入口,activityIdleInternal();
  AndroidApp的运行环境:ApplicationFramework,将整个操作系统分隔成两个部分;Dalvik虚拟机采用寄存器架构,而不是JVM的栈结构;LinuxKernel,每个DalvikVM的每个Instance都对应于Linux内核中的一个进程;
  Linux内核中的内存回收,lowmemorykiller;
  类ActivityManagerService中涉及到内存回收的几个重要的成员方法如下:trimApplications(),updateOomAdjLocked(),activityIdleInternal();
  LRU是Least Recently Used 近期最少使用算法;
  磁盘缓存,可以用的HashMap<String,String>,key为文件路径,value为decode出来的小图存放的文件路径;内存缓存,可以用个LinkedHashMap,采用FIFO(先进先出的原则),将最近的N的小图保存起来;
  BitmapFactory.Options opts=new BitmapFactory.Options();opts.inJustDecodeBounds=true;//仅取文件属性,但不分配内存;opts.inSampleSize=2;//缩放比例,取最接近的;
  优化gallery展示:三个图片,无限循环,利用new WeakReference<ImageView>(ivNew);   System.identityHashCode(ivRefer.get());
 用完之后,要及时释放,不要依赖GC;缓存利用WeakReference;通过Resources,会根据目录结构/分辨率自调整大小;scale=opts.inTargetDensity/(float)opts.inDensity;调整大小;
  手机设备的标准分辨率为160dpi; 像素(pixel)=尺度(inch)*分辨率(dot/inch);  
  array[i]=getResources().getDrawable(R.drawable.item_test);//drawable目录,k900,total,1008;width,8295;height,2280;//内部调用mResources.getCachedDrawable(*);使用了WeakReference;
  array[i]=Drawable.createFromStream(getResources().openRawResource(R.drawable.item_test),null);//drawable目录,k900,23,crash;width,2765;height,760;内部调用BitmapFactory.decodeResourceStream(*);
  bitmap[i]=BitmapFactory.decodeResource(getResources(),R.drawable.item_test);//drawable目录,k900,3,crash;ByteCount,75650400;width,8295;height,2280;根据目录结构/分辨率自调整大小;
     BitmapFactory.decodeResource(*);//内部调用decodeResourceStream(*);根据目录结构/分辨率自调整大小;scale=opts.inTargetDensity/(float)opts.inDensity;调整大小;
     内部再调用decodeStream(*);//内部根据InputSteam类型,再调用nativeDecodeStream(*),或者nativeDecodeAsset(*);//最终都是调用BitmapFactory.cpp的doDecode(*);
  bitmap[i]=BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.item_test));//drawable目录,k900,23,crash;ByteCount,8405600;width,2765;height,760;
     getResources().openRawResource(*)的inputStream为AssetInputStream;//BitmapFactory根据InputSteam类型,再调用nativeDecodeStream(*),或者nativeDecodeAsset(*);     



  Android操作系统中的内存回收可分为两个层次,默认内存回收与内核级内存回收;
  内存回收:回收动作入口,activityIdleInternal();回收过程函数trimApplications();
  Android系统中内存回收的触发点有三种情况(最终调用的函数接口是activityIdleInternal()):用户程序调用StartActivity(),使当前活动的Activity被覆盖;用户按back键,退出当前应用程序;启动一个新的应用程序;
  Android4.3,trimApplications():首先检查mRemovedProcesses列表中的进程,调用Process.killProcess将所有此类进程全部杀死;调用updateOomAdjLocked()函数;如果当前依然运行了过多的Activity,对多余的Activity进行回收;
  Linux内核中的内存回收:lowmemorykiller;调用updateOomAdjLocked()的函数,如果返回false,则执行默认回收,若返回true则不执行默认内存回收;
  ActivityManagerService杀死进程调用Process.killProcessQuiet(app.pid);

  普通虚拟机内存回收算法:标记-清除;复制;标记-整理;分代收集;     收集器有三种:串行收集器;并行收集器;并发收集器;
  DalvikVM则不同,在进行GC的时候会单独申请一块空间,以位图的形式来保存整个堆上的对象的标记,在GC结束后就释放该空间;
  在标记阶段,从根集合开始,沿着对象用的引用进行标记直到没有更多可标记的对象为止;标记结束后,被标记的就是活着的对象,没被标记到的就是“垃圾”;在清除阶段,DalvikVM并不直接对堆做什么操作,而是在一个记录分配状况的位图上把被认为是垃圾的对象所在位置的分配标记清零;为了不让这个位图太大,位图中并不是每一位对应到堆上的一个字节,而是对应到一块固定大小的空间;为此,堆空间的分配也是有一定对齐的;
  只进行标记-清除,在经过多次GC后可能会使堆被碎片化;Android所实现的libc(称为Bionic)对这种情况有特别的实现,可以避免碎片化问题;




发布了8 篇原创文章 · 获赞 7 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/liu31187/article/details/22870853
今日推荐