android内存管理了解课件_第1页
android内存管理了解课件_第2页
android内存管理了解课件_第3页
android内存管理了解课件_第4页
android内存管理了解课件_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、android内存管理了解1 Android内存管理认识 2 目录 Low Memory Killer Ashmem Pmem dalvik虚拟机内存管理 3 低内存管理器(Low Memory Killer) 低内存管理器(Low Memory Killer) ,相对于Linux标准OOM (Out Of Memory)机制更加灵活,它可以根据需要杀死进程来释放需 要的内存。 源代码位于drivers/staging/Android/lowmemorykiller.c 匿名共享内存(ashmem) ,为进程间提供大块共享内存,同时为 内核提供回收和管理这个内存的机制。 源代码位于mm/ash

2、mem.c Android PMEM(Physical) ,PMEM用于向用户空间提供连续的 物理内存区域,DSP和某些设备只能工作在连续的物理内存上。 源代码 位于drivers/misc/pmem.c 4 Low Memory Killer的实现 Low Memory Killer的源代码在drivers/staging/android/lowmemorykiller.c 中,它是通过注册Cache Shrinker来实现的。Cache Shrinker是标准 linux kernel回收内存页面的一种机制,它由内核线程kswapd监控, 当空闲内存页面不足时,kswapd会调用注册的Sh

3、rinker回调函数,来 回收内存页面。 Low Memory Killer是在模块初始化时注册Cache Shrinker的,代码如下: static int _init lowmem_init(void) register_shrinker( / 注册 Cache Shrinker return 0; lowmem_shrinker的定义如下: static struct shrinker lowmem_shrinker = .shrink = lowmem_shrink, .seeks = DEFAULT_SEEKS * 16 ; 5 register_shrinker 会将lowmem

4、_shrink 加入Shrinker List 中,被kswapd 在遍历Shrinker List 时调用, 而Low Memory Killer 的功能就是在lowmem_shrink 中实现的。 lowmem_shrink 用两个数组作为选择Bad 进程的依据,这两个数组的定义如下: static int lowmem_adj6 = 0, 1, 6, 12, ; static int lowmem_adj_size = 4; static size_t lowmem_minfree6 = 3*512, / 6MB 2*1024, / 8MB 4*1024, / 16MB 16*1024,

5、 / 64MB ; lowmem_shrink 首先计算当前空闲内存的大小,如果小于某个阈值,则以该阈值对应的优先级为基准, 遍历各个进程,计算每个进程占用内存的大小,找出优先级大于基准优先级的进程,在这些进程中选择 优先级最大的杀死,如果优先级相同,则选择占用内存最多的进程。 lowmem_shrink 杀死进程的方法是向进程发送一个不可以忽略或阻塞的SIGKILL 信号: force_sig(SIGKILL, selected); 6 用户接口 设置空闲内存阈值的接口: /sys/module/lowmemorykiller/parameters/minfree,设置 对应优先级的接口:

6、/sys/module/lowmemorykiller/parameters/adj,设置各个 进程优先级的接口: /proc/oom_adj。 Android 启动时读取的配置文件/init.rc 中定义了相应的属性 供AP 使用并有设置这些参数。 将init进程oom_adj设置为-16,从而保证init进程永远不会被 杀掉。 7 Ashmem相关介绍 基本原理 Android 的Ashmem是一种共享内存的机制,它基于mmap系统调用,不 同进程可以将同一段物理内存映射到各自的虚拟地址控制,从而实现 共享。 Ashmem与mmap的区别 mmap通过映射同一个普通文件实现进程间共享内存,

7、普通文件被映射 到进程地址空间后,进程可以像访问普通内存一样对文件进行访问, 不必再调用read,write等操作。进程在映射空间对共享内存的改变并 不直接写回到磁盘文件中,在调用munmap后才执行此操作。可以通 过调用msync实现磁盘上文件内存与共享内存区的内容一致。 Ashmem与mmap的区别在于Ashmem与cache shrinker关联起来,可以 控制cache shrinker在适当时机回收这些共享内存。 8 Ashmem的实现 Ashmem的源代码在mm/ashmem.c中,它通过注册Cache Shrinker回收内存,通过注册misc设备提供open,mmap 等接口,

8、mmap则通过tmpfs创建文件来分配内存,tmpfs 将一块内存虚拟为一个文件,这样操作共享内存就相当于 操作一个文件。 Ashmem用两个结构体ashmem_area和ashmem_range来维 护分配的内存,ashmem_area代表共享的内存区域, ashmem_range则将这段区域以页为单位分为多个range。 ashmem_area有个unpinned_list成员,挂在这个list上的 range可以被回收。ashmem_range有一个LRU链表,在 cache shrink回收一个ashmem_area的某段内存时候,是 根据LRU的原则来选择哪些页面优先被回收的。 9

9、Ashmem的基本结构 10 主要函数功能简单分析 ashmem_init 这是module初始化函数,Ashmem是作为一个模块实现的。该函数主要功能: 调用kmem_cache_create分别创建struct ashmem_area和struct ashmem_range 的 slab cache 调用misc_register注册 ahsmem driver 调用register_shrinker注册Ashmem的 Cache Shrinker ashmem_open 标准misc设备的open函数。它调用kmem_cache_zalloc分配一个 ashmem_area,并初始 化各

10、成员变量。 ashmem_release 做与ashmem_open相反工作,释放tmpfs文件,ashmem_area及其ashmem_range。 ashmem_mmap mmap操作,主要就是调用shmem_从tmpfs文件系统中创建一个文件(实际上就 是一段RAM)给ashmem_area用,该文件代表着这段被共享的内存。Ashmem真正实现进 程共享内存的机制是靠shmem这个linux标准机制提供的。 11 主要函数功能简单分析 ashmem_shrink 即Ashmem的cache shrink函数。它被mm/vmscan.c:shrink_slab调用,或者 被用户的 ioct

11、l 命令调用。这个函数从LRU链表上回收指定数目的 unpinned ashmem_range。 ashmem_ioctl 这个函数提供ioctl 接口,它实现了如下命令: 12 主要函数功能简单分析 ashmem_unpin unpin一段内存。实现的方法很简单,就是分配一个ashmem_range,把它挂到 ashmem_area - unpinned_list上,并加到 LRU链表上。 ashmem_pin pin一段内存,从 ashmem_area-unpinned_list上拿下这个 ashmem_range, 由此可知,被unpin的range才能被回收,pin的range则不能回

12、收。 用户接口 Ashmem驱动创建了/dev/ashmem设备文件,进程A可通过open打开该文件, 用ioctl命令ASHMEM_SET_NAME和ASHMEM_SET_SIZE设置共享内存块的 名字和大小,并将得到的handle传给mmap,来获得共享的内存区域,进程B 通过将相同的handle传给mmap,获得同一块内存,handle在进程间的传递可 通过Binder来实现。 13 Pmem相关介绍 基本原理 Android Pmem是为了实现共享大尺寸连续物理内存而 开发的一种机制,该机制对dsp,gpu等部件非常有用。 Pmem相当于把系统内存划分出一部分单独管理,即不被 linu

13、x mm管理,实际上linux mm根本看不到这段内存。 Pmem与Ashmem的区别 Pmem和Ashmem都通过mmap来实现共享内存,其区 别在于Pmem的共享区域是一段连续的物理内存,而 Ashmem的共享区域在虚拟空间是连续的,物理内存却不 一定连续。dsp和某些设备只能工作在连续的物理内存上, 这样cpu与dsp之间的通信就需要通过Pmem来实现。 14 Pmem的实现 Pmem的源代码在drivers/misc/pmem.c中,Pmem驱动依赖于 linux的misc device和platform driver框架,一个系统可以有多个 Pmem,默认的是最多10个。Pmem暴露

14、4组操作,分别是platform driver的probe和remove操作; misc device的fops接口和vm_ops操作。 模块初始化时会注册一个platform driver,在之后probe时,创建misc 设备文件,分配内存,完成初始化工作。 Pmem通过pmem_info,pmem_data,pmem_region三个结构体 维护分配的共享内存,其中pmem_info代表一个Pmem设备分配的内 存块,pmem_data代表该内存块的一个子块,pmem_region则把每 个子块分成多个区域。 pmem_data是分配的基本单位,即每次应用 层要分配一块Pmem内存,就会

15、有一个pmem_data来表示这个被分配 的内存块,实际上在open的时候,并不是open一个pmem_info表示 的整个Pmem内存块,而是创建一个pmem_data以备使用。一个应用 可以通过ioctl来分配 pmem_data中的一个区域,并可以把它map到进 程空间;并不一定每次都要分配和map整个pmem_data内存块。 15 dalvik虚拟机内存管理 android模式 linux模式 16 dalvik虚拟机内存管理 内存管理的核心就是两个部分:分配内存和回收内存。 Java语言使用new操作符来分配内存,但是与C/C+等语 言不同的是,Java语言并没有提供任何操作来释放

16、内存, 而是通过一种叫做垃圾收集的机制来回收内存。对于内存 管理的实现,我们通过三个方面来加以分析:内存分配, 内存回收和内存管理调试。 17 对象布局 所有的对象都有一个相同的头部clazz和lock。 (1)clazz:clazz指向该对象的类对象,类对象用来描述该对象所属的类,这样可 以很容易的从一个对象获取该对象所属的类的具体信息。 (2)lock:是一个无符号整数,用以实现对象的同步。 (3)data:存放对象数据,根据对象的不同数据区的大小是不同的。 内存管理的主要操作之一是为Java对象分配内存,Java对象在虚拟机中的内存布 局如下: 18 堆 堆是dalvik虚拟机从操作系统

17、分配的一块连续的虚拟 内存。heapBase是堆的起始地址,heapLimit是堆的最大 地址,堆大小的最大值可以通过-Xmx选项或 dalvik.vm.heapsize指定。在原生系统中,一般 dalvik.vm.heapsize值是32M,在MIUI中我们将其设为 64M。 在dalvik虚拟机实现中,是通过底层的bionicC库的 malloc/free操作来分配/释放内存的。bionicC库的 malloc/free操作是基于DougLea的实现(dlmalloc) 19 堆内存位图 在虚拟机中维护了两个对应于堆内存的位图,称为liveBits和 markBits。 在对象布局中,我们

18、看到对象最小占用8个字节。在为对象分配内 存时要求必须8字节对齐。这也就是说,对象的大小会调整为8字节的 倍数。比如说一个对象的实际大小是13字节,但是在分配内存的时候 分配16字节。因此所有对象的起始地址一定是8字节的倍数。堆内存 位图就是用来描述堆内存的,每一个bit描述8个字节,因此堆内存位 图的大小是对的64分之一。对于MIUI的实现来说,这两个位图各占 1M。 liveBits的作用是用来跟踪堆中以分配的内存,每分配一个对象时, 对象的内存起始地址对应于位图中的位被设为1。在下一篇垃圾收集 中我们会进一步的分析liveBits和markBits这两个位图的作用。 20 dvmAllo

19、cObject dvmAllocObject在dalvik虚拟机中,new操作符最终对应dvmAllocObject这个C函数。 下面通过伪码的形式列出dvmAllocObject的实现。 Object*dvmAllocObject(ClassObject *clazz, int flags) n = get object size form class object clazz first try: allocate n bytes from heap if first try failed run garbage collector without collecting soft refe

20、rences second try: allocate n bytes from heap if second try failed third try: grow the heap and allocate n bytes from heap (注释:堆是虚拟内存,一开始并未分配所有的物理内存,只要还没有达到虚拟内存的最 大值,可以通过获取更多物理内存的方式来扩展堆) if third try failed run garbage collector with collecting soft references fourth try: grow the hap and allocate n

21、 bytes from heap if fourth try failed, return null pointer, dalvik vm will abort 可以看出,为了分配内存,虚拟机尽了最大的努力,做了四次尝试。其中进行了两次 垃圾收集,第一次不收集SoftReference,第二次收集SoftReference。从中我们也可以 看出垃圾收集的时机,实质上在dalvik虚拟机实现中有3个时机可以触发垃圾收集的运 行: (1)程序员显式的调用System.gc() (2)内存分配失败时 (3)如果分配的对象大小超过384KB,运行并发标记(concurrent mark), 21 垃圾

22、回收 在dalvik虚拟机中,内存分配操作的流程相对比较简 单直观,从一个堆中分配可用内存,分配失败时触发垃圾 收集。 垃圾收集是dalvik虚拟机内存管理的核心,垃圾收集 的性能在很大程度上影响了一个Java程序内存使用的效率。 顾名思义,垃圾收集就是收集垃圾内存加以回收。dalvik 虚拟机使用常用的Mark-Sweep算法,该算法一般分Mark 阶段(标记出活动对象),Sweep阶段(回收垃圾内存) 和可选的Compact阶段(减少堆中的碎片)。dalvik虚拟 机的实现不进行可选的Compact阶段。 22 Mark 垃圾收集的第一步是标记出活动对象,因为没有办法识别那些不可访问的 对

23、象(unreachableobjects),因此我们只能标记出活动对象,这样所有未被标记 的对象就是可以回收的垃圾 1.1 根集合根集合(RootSet) 当进行垃圾收集时,需要停止dalvik虚拟机的运行(当然,除了垃圾收集之外)。 因此垃圾收集又被称作STW(stop-the-world,整个世界因我而停止)。dalvik 虚拟机在运行过程中要维护一些状态信息,这些信息包括:每个线程所保存的 寄存器,Java类中的静态字段,局部和全局的JNI引用,JVM中的所有函数调用 会对应一个相应C的栈帧。每一个栈帧里可能包含对对象的引用,比如包含对象 引用的局部变量和参数。 所有这些引用信息被加入到

24、一个集合中,叫根集合。然后从根集合开始,递归 的查找可以从根集合出发访问的对象。因此,Mark过程又被成为追踪,追踪所 有可被访问的对象。如下图所示,假定从根集合a开始,我们可以访问的对象 集合为a,b, c, d,这样就追踪出所有可被访问的对象集合。 (5.98 KB) 1.2 标记栈标记栈(MarkStack) 垃圾收集使用栈来保存根集合,然后对栈中的每一个元素,递归追踪所有可访 问的对象,对于所有可访问的对象,在markBits位图中该将对象的内存起始地址 对应的位设为1。这样当栈为空时,markBits位图就是所有可访问的对象集合。 23 Concurrent Mark(并发标记并发标

25、记) 为了运行垃圾收集,需要停止虚拟机的运行,这可能 会导致程序比较长时间的停顿。垃圾收集的主要工作位于 Mark阶段,为了缩短停顿时间,dalvik虚拟机使用了 concurrentmark技术。Concurrentmark引入一个单独的gc 线程,由该线程去跟踪自己的根集合中所有可访问的对象, 同时所有其它的线程也在运行。这也是concurrent一词的 含义,但是为了回收内存,即运行Sweep阶段,必需停止 虚拟机的运行。这会导入一个问题,即在gc线程mark对 象的时候,其它线程的运行又引入了新的访问对象。因此 在Sweep阶段,又重新运行mark阶段,但是在这个阶段 对于已经mark的对象可以不用继续递归追踪了。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论