管理Android程序的内存

      在任何的软件开发环境中,RAM都是宝贵的资源,在手机操作系统中他显得更加宝贵,因为在手机中RAM通常是很有限的。虽然Android的Dalvik虚拟机执行日常的垃圾回收,但是你还是要关注一下你所编写的程序的内存分配与回收。
     为了让垃圾回收器从你的应用程序回收内存,你需要避免引入内存泄漏(通常是因为在全局变量中持有对象引用而引起的)在适当的时间释放对象。对于大多数的应用,Dalvik垃圾回收器负责:
     当对应的对象不在应用程序的活动线程范围内时回收该对象所占用的内存。
     本文主要讲解Android怎样管理应用程序的进程和内存分配以及在开发Android应用时怎样减少内存的使用。


Android怎样管理内存

    Android 没有为内存提供交换空间,但它使用分页和内存映射(mmapping)来管理内存。也就是说你对内存作的任何修改(无论是通过new一个对象来分配内存还是触发内存映射页)仍然驻留在内存中不能被换出。完全释放内存的唯一方式是通过释放对象所持有的引用使其能够被垃圾回收器回收。有一个例外情况:没有修改任何文件的内存映射,例如当系统想要在其它地方使用内存的时候,程序的代码可能是被换出的。


共享内存

     为了满足一切内存需要,Android尝试跨进程共享RAM页。他采用下边的这些方式:
 
 
  • 每个应用程序的进程都是从一个名为Zygote(受精卵)的进程分叉而来。当系统启动和加载通用框架代码以及资源(如activity的主题)时Zygote进程被启动。为了启动一个新的应用进程,系统会分叉Zygote进程。然后在这个新进程中加载和运行应用程序的代码。为了框架代码和资源能被所有的应用程序进程共享,系统为其分了配大部分的内存页。
  • 进程里的大多数静态数据是被内存映射的。它不仅允许相同的数据在进程间共享而且在必要的时候允许这些数据从RAM中换出。静态数据的例子:虚拟机代码(为了直接映射它放置它在一个预连接文件.odex中)、应用程序资源、传统的项目元素如本地代码.so文件。
  • 在许多地方,Android在进程间使用显式分配的共享内存区域共享相同的动态随机存取存储器(ashmem 或 gralloc).例如Cursor缓冲区在内容提供者和客户端间使用了共享内存。

应用程序的内存分配与回收

以下是android为你的应用程序分配内存与回收内存的一些情况
  • 每个进程的Dalvik堆是被限制在一个单独的虚拟内存范围。它定义了在需要的时候它能够增长的堆的逻辑大小(但是只能增长到系统为每个应用程序所限定的大小)
  • 堆的逻辑大小与堆使用的物理内存的数量是不相同的。当检查应用程序的堆的时候,Android会计算当前应用程序进程与其它进程共享的内存中已经使用的页和尚未使用的页的大小的值。
  • Dalvik堆不会压缩堆的逻辑大小,意味着Android不会为了回收空间而重组堆。当堆的末尾有未使用的空间时,Android才会缩小堆的大小。但这并不意味着堆所使用的物理内存不能被减少。垃圾收集后,Dalvik遍历堆并找到未使用的页,然后使用madvise函数返回这些页到内核。因此成对的大块的内存分配和再分配应该会导致回收所有的(几乎所有的)物理内存占用。然而,回收小的内存可能效率是更加低下的因为这些小的内存分配所使用的页可能在别的地方是被共享的未被释放的。

限制应用程序内存

    为了保持多任务功能环境,Android为每个应用程序的堆大小作了一个硬性的限制。不同设备的准确堆限制取决于设备所拥有的可用内存大小。假如应用程序所使用的内存已经达到了它所限制的堆容量,在这种情况下程序如果试图继续分配更多的内存,则程序会接收到OutOfMemoryError。
     在某些情况下,你可能想要查询当前设备究竟有多少堆空间是可用的----例如,确定保存多少数据在缓存中是安全的。你可以调用getMemoryClass()查询你的应用所能使用的堆空间大小。getMemoryClass()返回一个整形的数据指示你的应用程序所能使用的有效堆空间的大小。

切换应用

    用户切换两个应用程序时系统并不使用交换空间,android将没有持有前景状态的应用程序组件的进程保存在一个叫做最近较少使用(LRU)的缓存中。例如,当用户第一次启动一个应用的时候,系统会为这个应用创建一个进程,但是当用户离开这个应用的时候,这个应用程序的进程并没有结束。系统会把这个应用程序的进程放在一个缓存中。当用户稍后再次返回这个应用的时候,在缓存中的进程是被系统重用的以便用户能够快速切换到这个应用。
    如果你的应用程序的进程是被缓存在LRU中,但是当前它是不需要的,即使用户没有使用它,它对系统的整体性能还是会有一定坏的影响的。当系统的内存不足时,存储在LRU中的进程可能会被杀死。你应该考虑到进程会占用许多内存,为了使应用程序的进程尽可能久的保存在LRU缓存中,你应该及时合理的释放掉对象所持有的引用。
下一篇将会介绍应该怎样管理你的应用程序的内存的一些方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值