Android内存管理原理 (整理汇总)

Android内存管理原理 (整理汇总)

ID:39464546

大小:288.50 KB

页数:20页

时间:2019-07-03

Android内存管理原理 (整理汇总)_第1页
Android内存管理原理 (整理汇总)_第2页
Android内存管理原理 (整理汇总)_第3页
Android内存管理原理 (整理汇总)_第4页
Android内存管理原理 (整理汇总)_第5页
资源描述:

《Android内存管理原理 (整理汇总)》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、Android内存管理原理一般来说,程序使用内存的方式遵循先向操作系统申请一块内存,使用内存,使用完毕之后释放内存归还给操作系统。然而在传统的C/C++等要求显式释放内存的编程语言中,记得在合适的时候释放内存是一个很有难度的工作,因此Java等编程语言都提供了基于垃圾回收算法的内存管理机制:1.垃圾内存回收算法常见的垃圾回收算法有引用计数法(ReferenceCounting)、标注并清理(MarkandSweepGC)、拷贝(CopyingGC)和逐代回收(GenerationalGC)等算法,其中Android系统采用的是

2、标注并删除和拷贝GC,并不是大多数JVM实现里采用的逐代回收算法。由于几个算法各有优缺点,所以在很多垃圾回收实现中,常常可以看到将几种算法合并使用的场景,本节将一一讲解这几个算法。1.引用计数回收法(ReferenceCountingGC)引用计数法的原理很简单,即记录每个对象被引用的次数。每当创建一个新的对象,或者将其它指针指向该对象时,引用计数都会累加一次;而每当将指向对象的指针移除时,引用计数都会递减一次,当引用次数降为0时,删除对象并回收内存。采用这种算法的较出名的框架有微软的COM框架,如代码清单14-1演示了一个对

3、象引用计数的增减方式。代码清单14-1引用计数增减方式演示伪码Object*obj1=newObject();//obj1的引用计数为1Object*obj2=obj1;//obj1的引用技术为2Object*obj3=newObject(); obj2=NULL;//obj1的引用计数递减1次为1。obj1=obj3;//obj1的引用计数递减1次为0,可以回收其内存。 通常对象的引用计数都会跟对象放在一起,系统在分配完对象的内存后,返回的对象指针会跳过引用计数部分,如代码清单14-1所示:图14-1采用引用计数对象的内存布

4、局示例然而引用计数回收算法有一个很大的弱点,就是无法有效处理循环引用的问题,由于Android系统没有使用该算法,所以这里不做过多的描述,请有兴趣的读者自行查阅相关文档。1.标注并清理回收法(MarkandSweepGC)在这个算法中,程序在运行的过程中不停的创建新的对象并消耗内存,直到内存用光,这时再要创建新对象时,系统暂停其它组件的运行,触发GC线程启动垃圾回收过程。内存回收的原理很简单,就是从所谓的"GCRoots"集合开始,将内存整个遍历一次,保留所有可以被GCRoots直接或间接引用到的对象,而剩下的对象都当作垃圾对

5、待并回收,如代码清单14-3:代码清单14-2标注并清理算法伪码voidGC(){SuspendAllThreads(); Listroots=GetRoots();foreach(Objectroot:roots){Mark(root);} Sweep(); ResumeAllThreads();}算法通常分为两个主要的步骤:·标注(Mark)阶段:这个过程的伪码如代码清单14-2所示,针对GCRoots中的每一个对象,采用递归调用的方式(第8行)处理其直接和间接引用到的所有对象:代码清单14-3标注并清理的

6、标注阶段伪码1.voidMark(Object*pObj){2.if(!pObj->IsMarked()){3.    //修改对象头的Marked标志4.    pObj->Mark();5.    //深度优先遍历对象引用到的所有对象6.    Listfields=pObj->GetFields();7.    foreach(Object*field:fields){8.    Make(field);//递归处理引用到的对象9.    }10.}11.}如果对象引用的层次过深,递归调用消耗完虚拟机内

7、GC线程的栈空间,从而导致栈空间溢出(StackOverflow)异常,为了避免这种情况的发生,在具体实现时,通常是用一个叫做标注栈(MarkStack)的数据结构来分解递归调用。一开始,标注栈(MarkStack)的大小是固定的,但在一些极端情况下,如果标注栈的空间也不够的话,则会分配一个新的标注栈(MarkStack),并将新老栈用链表连接起来。与引用计数法中对象的内存布局类似,对象是否被标注的标志也是保存在对象头里的,如图14-2所示。图14-2标注和清理算法中的对象布局如图14-2是垃圾回收前的对象之间的引用关系;GC

8、线程遍历完整个内存堆之后,标识出所以可以被"GCRoots"引用到的对象-即代码清单14-2中的第4行,结果如图14-3中高亮的部分,对于所有未被引用到(即未被标注)的对象,都将其作为垃圾收集。图14-3回收内存垃圾之前的对象引用关系 图14-4GC线程标识出所有不能被回收的

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。