Android——内存管理基础

时间:2022-12-17 15:09:16

内存收集概念

内存垃圾收集器(garbage collector)

概念:自定内存管理。

功能:分配内存、保证所有被引用的对象还在内存中、可以释放在运行的代码中不再引用的对象的内存。

垃圾收集器避免了悬挂指针(dangling reference),原因是一个仍然被引用的对象永远不会内存回收并且也不会被认为已经被释放掉了。

垃圾收集器解决了空间泄漏(space leaks)问题,原因是它可以自动释放不再被引用的空间。

垃圾收集(garbage collection)

如果对象被引用着,那我们说它活着(live);如果对象不再被引用了,那我们说他死了(dead),术语称作垃圾(garbage)。寻找并释放这些对象的空间的过程就做垃圾收集(garbagecollection)。

那么在什么时候会出发垃圾收集动作呢?一般来说整个堆或一部分被填满或者达到某一百分比数值时将被收集。

常见的三种垃圾收集器

串行(Serial):也被称为完全停顿(Stop-the-world)。当执行GC时,程序的线程都会被挂起。

并行(Parallel):圾收集工作被分成几部分,这些子部将会在不同的CPU上被同时执行。同时执行会使垃圾收集得更快,但是代价是会增加复杂性和潜在碎片。

并发(Concurrent):一个或者多个垃圾收集任务也可以并发的与应用程序同时执行。通常,一个并发收集器可以并发的执行垃圾收集的大部分工作,但是也会不可避免的引发一个小的停顿。

Android Garbage Collector发展

Android 1.0~2.2,Dalvik虚拟使用的垃圾收集机制有以下特点:

  1. Stop-the-word(完全停顿),也就是一个垃圾收集线程在执行的时候,其它的线程都停止;
  2. Full heap collection,也就是一次收集完全部的垃圾;
  3. 长等待,一次垃圾收集造成的程序中止时间通常都大于100ms。

Android 2.3~至今,Dalvik虚拟使用的垃圾收集机制得到了改进

  1. Cocurrent(并发),也就是大多数情况下,一个或多垃圾收集线程与其它线程是并发执行的;
  2. Partial collection,也就是一次可能只收集一部分垃圾;
  3. 短等待,一次垃圾收集造成的程序中止时间通常都小于5ms。

Dalvik虚拟机执行完成一次垃圾收集之后,我们通常可以看到类似以下的日志输出:

 D/dalvikvm(9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms  

在这一行日志中,GC_CONCURRENT表示GC原因,2049K表示总共回收的内存,3571K/9991K表示Java Object Heap统计,即在9991K的Java Object Heap中,有3571K是正在使用的,4703K/5261K表示External Memory统计,即在5261K的External Memory中,有4703K是正在使用的,2ms+2ms表示垃圾收集造成的程序中止时间。

Android内存管理

Dalvik虚拟机的内存大体上可以分为Java Object Heap、Bitmap Memory和Native Heap三种。

Java Object Heap

Java Object Heap是用来分配Java对象的,也就是我们在代码new出来的对象都是位于Java Object Heap上的。

Dalvik虚拟机在启动的时候,可以通过-Xms和-Xmx选项来指定Java Object Heap的最小值和最大值。为了避免Dalvik虚拟机在运行的过程中对Java Object Heap的大小进行调整而影响性能,我们可以通过-Xms和-Xmx选项来将它的最小值和最大值设置为相等。

Java Object Heap的最小和最大默认值为2M和16M,但是手机在出厂时,厂商会根据手机的配置情况来对其进行调整,例如,G1、Droid、Nexus One和Xoom的Java Object Heap的最大值分别为16M、24M、32M 和48M。我们可以通过ActivityManager类的成员函数getMemoryClass来获得Dalvik虚拟机的Java Object Heap的最大值。

ActivityManager类的成员函数getMemoryClass的实现如下所示:

 public class ActivityManager {
...... /**
* Return the approximate per-application memory class of the current
* device. This gives you an idea of how hard a memory limit you should
* impose on your application to let the overall system work best. The
* returned value is in megabytes; the baseline Android memory class is
* 16 (which happens to be the Java heap limit of those devices); some
* device with more memory may return 24 or even higher numbers.
*/
public int getMemoryClass() {
return staticGetMemoryClass();
} /** @hide */
static public int staticGetMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
} ......
}

Dalvik虚拟机在启动的时候,就是通过读取系统属性dalvik.vm.heapsize的值来获得Java Object Heap的最大值的,而ActivityManager类的成员函数getMemoryClass最终也通过读取这个系统属性的值来获得Java Object Heap的最大值。

这个Java Object Heap的最大值也就是我们平时所说的Android应用程序进程能够使用的最大内存。这里必须要注意的是,Android应用程序进程能够使用的最大内存指的是能够用来分配Java Object的堆。

在Android3.0以及更高的版本中,我们还可以在AndroidManifest.xml的application标签中增加一个值等于“true”的android:largeHeap属性来通知Dalvik虚拟机应用程序需要使用较大的Java Object Heap。事实上这个属性受限于手机内存,同时也会影响系统体验(毕竟系统总共可用的内存是固定的,一个应用程序用得多了,就意味意其它应用程序用得少了)。

Bitmap Memory

Bitmap Memory也称为External Memory,它是用来处理图像的,这部分内存受Java Object Heap的大小限制的

  • 在Android3.0之前,Bitmap Memory是在Native Heap中分配的,但是这部分内存同样计入Java Object Heap中,也就是说,Bitmap占用的内存和Java Object占用的内存加起来不能超过Java Object Heap的最大值。这就是为什么我们在调用BitmapFactory相关的接口来处理大图像时,会抛出一个OutOfMemoryError异常的原因。
  • 在Android3.0以及更高的版本中,Bitmap Memory就直接是在Java Object Heap中分配了,这样就可以直接接受GC的管理。

Native Heap

Native Heap就是在Native Code中使用malloc等分配出来的内存,这部分内存是不受Java Object Heap的大小限制的,也就是它可以*使用,当然它是会受到系统的限制。但是有一点需要注意的是,不要因为Native Heap可以*使用就滥用,因为滥用Native Heap会导致系统可用内存急剧减少,从而引发系统采取激进的措施来Kill掉某些进程,用来补充可用内存,这样会影响系统体验。

Android——内存管理基础的更多相关文章

  1. Android 内存管理分析(四)

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...

  2. Android 内存管理研究

    1. 内存管理基础知识 http://www.cnblogs.com/xingfuzzhd/p/3485924.html 1. mImageView.setImageResource(R.drawab ...

  3. 浅谈Android内存管理

    最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误,仅仅知道这些,还是无法从整体上理解内存管理,对培养系统优 ...

  4. Android内存管理机制之一:low memory killer

    转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...

  5. OC内存管理基础

    OC 内存管理基础 一. retain和release基本使用 使用注意: 1.你想使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作) 2.你不想再使用(占用)某个对象,就 ...

  6. Objective-C内存管理基础

    2011-05-11 15:45 朱祁林 http://zhuqil.cnblogs.com 字号:T | T 本文我们将介绍<Objective-C内存管理基础>,在iOS开发中,内存管 ...

  7. 移动端测试&equals;&equals;&equals;Android内存管理&colon; 理解App的PSS

    Android内存管理: 理解App的PSS 原文链接:http://www.littleeye.co/blog/2013/06/11/android-memory-management-unders ...

  8. &lbrack;Android Memory&rsqb; Android内存管理、监测剖析

    转载自:http://blog.csdn.net/anlegor/article/details/23398785 Android内存管理机制: Android内存管理主要有:LowMemory Ki ...

  9. Android 内存管理 &amp&semi;Memory Leak &amp&semi; OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...

随机推荐

  1. imx6sl 调试记录

    公板芯片型号:MCIMX6L8DVN10AB 我的板子芯片型号:MCIMX6L2EVN10AB no GPU ,no EPDC 调板子时一定要注意,首先要搞清楚硬件芯片的具体差异,然后去nxp的官网找 ...

  2. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

  3. linux安装bind with DLZ &lt&semi;NIOT&gt&semi;

    2015年6月11日 1.sudo wget ftp://ftp.isc.org/isc/bind9/9.10.1/bind-9.10.1.tar.gz  或者 使用“rz”命令 2.tar -zxv ...

  4. Linux查看网络端口

    简单的总结一下前段时间学习Linux的成果 查看 TCP 22 端口是否打开1.列出所有端口:[root@Demon proc]# netstat -ntlpActive Internet conne ...

  5. javascript 函数后面有多个小括号f&lpar; &rpar;&lpar; &rpar;&lpar; &rpar;&period;&period;&period;

    有时我们看见js函数后面跟着多个小括号是什么意思?f( )( )( )... f()执行f函数,返回子函数 f()()执行子函数,返回孙函数 f()()()执行孙函数,返回重孙函数 ... ... 但 ...

  6. Maths &vert; 为什么点积等价于投影后的乘积

    目录 1. 复习点积 2. 点积的对称性 3. 矩阵与变换的关系 4. 一维矩阵也是一种线性变换 5. 最终解释:为什么是投影 先上结论: \(\boldsymbol v\)和\(\boldsymbo ...

  7. 在centos和redhat上安装docker

    前置条件 64-bit 系统 kernel 3.10+一.检查内核版本,返回的值大于3.10即可 $ uname -r 二.使用 sudo 或 root 权限的用户登入终端 三.卸载旧版本(如果安装过 ...

  8. 下拉列表JComboBox,列表框JList

    1.下拉列表JComboBox public class Demo extends JFrame { public Demo() { setBounds(100, 100, 200, 100); se ...

  9. java实现点选汉字验证码

    package com.rd.p2p.web; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; im ...

  10. 关于HTML框架&lpar;frameset&rpar;的一些基本用法

    frameset 定义 W3C是这样定义frameset框架的,通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面.每份HTML文档称为一个框架,并且每个框架都独立于其他的框架.注意,这是HTM ...