Android内存框架:内存管理系统

2839次阅读  |  发布于5年以前

一 Android内存管理流程

Android内存的管理流程如下所示:

  1. ActivityManagerService负责根据各种策略算法计算进程的adj值,也就是进程的优先级评分,它告诉内核这些进程的优先级是怎样的,内核根据这些优先级就行进程的kill和内存的回收。
  2. Linux内核内存管理系统根据进程的adj值进行进程的管理。

Java与C++之间有一堵由内存动态分配和垃圾收集技术围成的高墙,墙外的人想进去,墙里的人想出来。

内存结构

Java虚拟机在执行程序的时候会将内存划分为若干个不同的区域,这些区域有各自的用途以及创建、销毁时间,有些区域随着虚拟机进程启动而启动,有些则依赖用户线程的启动和结束 而建立和销毁。

Java虚拟机运行时的内存结构如下图所示:

内存分配

垃圾回收

提到垃圾回收,我们可以先思考一下,如果我们去做垃圾回收需要解决哪些问题? 🤔

一般说来,我们要解决一些三个问题:

这些问题分别对应着引用管理和回收策略等方案。

提到引用,我们都知道Java中有四种引用类型:

不同的引用类型,在做GC时会区别对待,我们平时生成的Java对象,默认都是强引用,也就是说只要强引用还在,GC就不会回收,那么如何判断强引用是否存在呢?🤔

一个简单的思路就是:引用计数法,有对这个对象的引用就+1,不再引用就-1,但是这种方式看起来简单美好,但它却不嫩解决循环引用计数的问题。

因此可达性分析算法登上历史舞台😎,用它来判断对象的引用是否存在。

可达性分析算法通过一系列称为GC Roots的对象作为起始点,从这些节点从上向下搜索,搜索走过的路径称为引用链,当一个对象没有任何引用链 与GC Roots连接时就说明此对象不可用,也就是对象不可达。

GC Roots对象通常包括:

可达性分析算法整个流程如下所示:

  1. 第一次标记:对象在经过可达性分析后发现没有与GC Roots有引用链,则进行第一次标记并进行一次筛选,筛选条件是:该对象是否有必要执行finalize()方法。没有覆盖finalize()方法或者finalize()方法已经被执行过都会被 认为没有必要执行
    • 如果有必要执行:则该对象会被放在一个F-Queue队列,并稍后在由虚拟机建立的低优先级Finalizer线程中触发该对象的finalize()方法,但不保证一定等待它执行结束,因为如果这个对象的finalize()方法发生了死循环或者执行 时间较长的情况,会阻塞F-Queue队列里的其他对象,影响GC。
  2. 第二次标记:GC对F-Queue队列里的对象进行第二次标记,如果在第二次标记时该对象又成功被引用,则会被移除即将回收的集合,否则会被回收。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8