美文网首页
Android的内存管理机制

Android的内存管理机制

作者: wan7451 | 来源:发表于2019-03-08 11:46 被阅读0次

    引用 https://www.csdn.net/article/2015-09-18/2825737/1
    该篇文件仅仅做了排版,方便阅读


    Google在Android的官网上有这样一篇文章,初步介绍了Android是如何管理应用的进程与内存分配:http://developer.android.com/training/articles/memory.html。 Android系统的Dalvik虚拟机扮演了常规的内存垃圾自动回收的角色,Android系统没有为内存提供交换区,它使用 paging与 memory-mapping(mmapping)的机制来管理内存,下面简要概述一些Android系统中重要的内存管理基础概念。

    1)共享内存

    Android系统通过下面几种方式来实现共享内存:

    • Android应用的进程都是从一个叫做Zygote的进程fork出来的。Zygote进程在系统启动,并载入通用的framework的代码与资源之后开始启动。为了启动一个新的程序进程,系统会fork Zygote进程生成一个新的进程,然后在新的进程中加载并运行应用程序的代码。这就使得大多数的RAM pages被用来分配给framework的代码,同时促使RAM资源能够在应用的所有进程之间进行共享。

    • 大多数static的数据被mmapped到一个进程中。这不仅仅让同样的数据能够在进程间进行共享,而且使得它能够在需要的时候被paged out。常见的static数据包括Dalvik Code、app resources、so文件等。

    • 大多数情况下,Android通过显式的分配共享内存区域(例如ashmem或gralloc)来实现动态RAM区域能够在不同进程之间进行共享的机制。比如,Window Surface在App与Screen Compositor之间使用共享的内存,Cursor Buffers在Content Provider与Clients之间共享内存。

    2)分配与回收内存

    每一个进程的Dalvik Heap都反映了使用内存的占用范围。这就是通常逻辑意义上提到的Dalvik Heap Size,它可以随着需要进行增长,但是增长行为会有一个系统为它设定上限。

    逻辑上讲的Heap Size和实际物理意义上使用的内存大小是不对等的,Proportional Set Size(PSS)记录了应用程序自身占用以及与其他进程进行共享的内存。

    Android系统并不会对Heap中空闲内存区域做碎片整理。系统仅仅会在新的内存分配之前判断Heap的尾端剩余空间是否足够,如果空间不够会触发GC操作,从而腾出更多空闲的内存空间。在Android的高级系统版本里面针对Heap空间有一个Generational Heap Memory的模型,最近分配的对象会存放在Young Generation区域。当这个对象在该区域停留的时间达到一定程度,它会被移动到Old Generation,最后累积一定时间再移动到Permanent Generation区域。系统会根据内存中不同的内存数据类型分别执行不同的GC操作。例如,刚分配到Young Generation区域的对象通常更容易被销毁回收,同时在Young Generation区域的GC操作速度会比Old Generation区域的GC操作速度更快(如图1所示)。


    图1 根据不同内存数据类型执行不同GC操作

    每一个Generation的内存区域都有固定的大小。随着新的对象陆续被分配到此区域,当对象总的大小临近这一级别内存区域的阀值时,会触发GC操作,以便腾出空间来存放其他新的对象(如图2所示)。


    图2 对象值临近阀值触发GC操作

    通常情况下,GC发生的时候,所有的线程都是会被暂停的。执行GC所占用的时间和它发生在哪一个Generation也有关系,Young Generation中的每次GC操作时间是最短的,Old Generation其次,Permanent Generation最长。执行时间的长短也和当前Generation中的对象数量有关,遍历树结构查找20000个对象比起遍历50个对象自然是要慢很多的。

    3)限制应用的内存

    为了整个系统的内存控制需要,Android系统为每一个应用程序都设置一个硬性的Dalvik Heap Size最大限制阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如果你的应用占用内存空间已经接近这个阈值,此时再尝试分配内存的话,很容易引发OutOfMemoryError错误。

    ActivityManager.getMemoryClass()可以用来查询当前应用的Heap Size阈值,这个方法会返回一个整数,表明应用的Heap Size阈值是多少MB(Megabates)。

    4)应用切换操作

    Android系统并不会在用户切换应用的时候执行交换内存操作。Android会把那些不包含Foreground组件的应用进程放到LRU Cache中。例如,当用户开始启动一个应用时,系统会为它创建一个进程。但是当用户离开此应用,进程不会立即被销毁,而是被放到系统的Cache当中。如果用户后来再切换回到这个应用,此进程就能够被马上完整地恢复,从而实现应用的快速切换。

    如果你的应用中有一个被缓存的进程,这个进程会占用一定的内存空间,它会对系统的整体性能有影响。因此,当系统开始进入Low Memory的状态时,它会由系统根据LRU的规则与应用的优先级,内存占用情况以及其他因素的影响综合评估之后决定是否被杀掉。

    对于那些非foreground的进程,Android系统是如何判断Kill掉哪些进程的问题,请参考Processes and Threads

    相关文章

      网友评论

          本文标题:Android的内存管理机制

          本文链接:https://www.haomeiwen.com/subject/vjtrpqtx.html