• 1. 讲师:svenDalvik虚拟机内存管理
  • 2. *版本控制版本号主要变更内容变更日期作者审批审批日期1.0初版2012.05.15sven
  • 3. *1学习目标基本概念及术语 Dalvik虚拟机内存管理
  • 4. *2基本概念及术语Java虚拟机内存区域分类
  • 5. *3基本概念及术语垃圾收集算法: 标记-清除算法(Mark-Sweep Collector) 复制算法(Coping Collector) 标记-整理算法(Mark-CompactCollector) 分代算法(Generational Collector) 一种垃圾收集器 CMS收集器
  • 6. *4基本概念及术语标记-清除(Mark-Sweep)算法:标记-清除采用的方式为从根集合开始扫描,对存活的对象 进行标记,标记完毕后,再扫描整个空间中未标记的对象,并进行回收。过程:优缺点:在空间中存活对象较多的情况下较为高效,但由于该算法为 直接回收不存活对象所占用的内存,因此会造成内存碎片。
  • 7. *5基本概念及术语复制算法(Copying) 复制算法:复制采用的方式为从根集合扫描出存活的对象,并将找到的存 活对象复制到一块新的完全未使用的空间中。优缺点:可以不用考虑内存碎片问题,只是付出了一定空间的可用内存用于复制
  • 8. *6基本概念及术语标记-压缩(Mark-Compact) 算法:标记阶段与“标记-清除”算法相同,但在清除阶段有所不同。在回收不 存活对象所占用的内存空间后,会将其他所有存活对象都往左端空闲的空间进 行移动,并更新引用其对象指针。 过程: 优缺点:在“标记-清除”的基础上还需要进行对象移动,成本相对较高,好处 则是不产生内存碎片。
  • 9. *7基本概念及术语分代算法(Generational Collector) 分代算法:分代算法根据对象的存活周期不同,将内存划分为几块。一般分为新生代(Young Generation)和老年代(Old Generation)。这样可以根据各个年代的特点采用最合适的收集算法。 过程:注意,红叉为不存活的对象所占用内存空间
  • 10. *8基本概念及术语CMS收集器:Concurrent Mark-Sweep GC 算法:Mark –Sweep 过程: 1. 第一次标记(Initial Marking):暂停整个应用,扫描从根集合点 到内存中可直接访问到的对象,并进行标记; 2. 并发标记(Concurrent Marking):恢复所有应用的线程,同时 开始并发对之前标记过的对象进行轮循,以标记这些对象可访问的对象; 3. 重新标记(Remark):暂停整个应用,扫描在第二步中被改变引 用关系或新创建的对象,并进行标记; 4. 并发收集(Concurrent Sweeping):恢复所有应用的线程,将没有 标记的对象进行单线程回收。针对内存碎片,CMS会尽量将相邻的块重 新组装成一个块。
  • 11. 9基本概念及术语
  • 12. 10Dalvik虚拟机内存管理对象布局 内存管理的主要操作之一是为Java对象分配内存,Java对象在虚拟机中的内 存布局如下: 所有的对象都有一个头部clazz和lock。
  • 13. 11Dalvik虚拟机内存管理(1)clazz:clazz指向该对象的类对象,类对象用来描述该对象所属的类,这样可以很容易的从一个对象获取该对象所属的类的具体信息。 (2)lock:是一个无符号整数,用以实现对象的同步。 (3)data:存放对象数据,根据对象的不同数据区的大小是不同的。
  • 14. 12Dalvik虚拟机内存管理堆内存位图 在虚拟机中维护了两个对应于堆内存的位图,称为liveBits和markBits。 在对象布局中,我们看到对象最小占用8个字节。在为对象分配内存时要 求必须8字节对齐。这也就是说,对象的大小会调整为8字节的倍数。比如 说一个对象的实际大小是13字节,但是在分配内存的时候分配16字节。因 此所有对象的起始地址一定是8字节的倍数。堆内存位图就是用来描述堆内 存的,每一个bit描述8个字节,因此堆内存位图的大小是堆的64分之一。 liveBits的作用是用来跟踪堆中以分配的内存,每分配一个对象时,对象的 内存起始地址对应于位图中的位被设为1。
  • 15. 13Dalvik虚拟机内存管理
  • 16. 14Dalvik虚拟机内存管理堆的内存管理 在dalvik虚拟机实现中,是通过底层的bionicC库的malloc/free操作来 分配/释放内存的。bionicC库的malloc/free操作是基于DougLea的实 现(dlmalloc),这是一个被广泛使用,久经考验的C内存管理库,这里不 展开dlmalloc的具体实现。 有兴趣的读者请参考 http://g.oswego.edu/dl/html/malloc.html。
  • 17. 15Dalvik虚拟机内存管理内存分配 在dalvik虚拟机中,new操作符最终对应dvmAllocObject这个C函数。
  • 18. 16Dalvik虚拟机内存管理可以看出,为了分配内存,虚拟机做了四次尝试。其中进行了两次垃圾 收集,第一次不收集SoftReference,第二次收集 SoftReference。从中我们也可以看出垃圾收集的时机,实质上在dalvik虚 拟机实现中有3个时机可以触发垃圾收集的运行: (1)程序员显式的调用System.gc() 对应DEBUG信息:GC_EXPLICIT (2)内存分配失败时 对应DEBUG信息:GC_FOR_ALLOC (3)如果分配的对象大小超过384KB,运行并发标记(concurrent mark) 对应DEBUG信息:GC_CONCURRENT
  • 19. 17Dalvik虚拟机内存管理Dalvik的垃圾收集 算法: 标记-清除(mark sweep) 两种形式: 同步GC 并发标记GC
  • 20. 18Dalvik虚拟机内存管理根集合 包含的范围有: 1.每个线程所保存的寄存器 2.方法区中的常量池中的引用对象(包括类静态属性引用对象、常量属性引用对象)。 3.局部和全局的JNI引用 4.虚拟机栈中的引用对象 dalvik虚拟机使用根搜索算法,mark过程从根集合开始
  • 21. 19Dalvik虚拟机内存管理标记栈(MarkStack) 垃圾收集使用栈来保存根集合,然后对栈中的每一个元素,递归追踪所有 可访问的对象,对于所有可访问的对象,在markBits位图中该将对象的内 存起始地址对应的位设为1。这样当栈为空时,markBits位图就是所有可 访问的对象集合。
  • 22. 20Dalvik虚拟机内存管理清理 (Sweep) 垃圾收集的第二步就是回收内存,在Mark阶段通过markBits位图我们可以 得到所有可访问的对象集合,而liveBits位图表示所有已经分配的对象集合。 因此通过比较这两个位图,liveBits位图和markBits位图的差异就是所有可 回收的对象集合。Sweep阶段调用free来释放这些内存给堆。
  • 23. 21小结1.由于内存分配失败会导致多次GC,从实践的结果来看,同步GC一定会导致视觉上的卡、顿,因此需要避免在动画展示过程中创建对象。 2.concurrent gc的开销远小于同步GC,可以通过Log看到。 3.APK空闲时,可以显式调用system.gc来触发concurrent gc,可以有不错的效果。
  • 24. 谢谢!