[Android Memory] Android内存管理、监测剖析

转载自:http://blog.csdn.net/anlegor/article/details/23398785

Android内存管理机制:

Android内存管理主要有:LowMemory Killer机制,Ashmem,PMEM/ION及Native内存和Dalvik内存管理管理和JVM垃圾回收机制。

LowMemory Killer机制:

源码位置drivers/staging/Android/lowmemorykiller.c

Android是一个多任务系统,也就是说可以同时运行多个程序,这个大家应该很熟悉。一般来说,启动运行一个程序是有一定的时间开销的,因此为了加快运行速度,当你退出一个程序时,Android并不会立即杀掉它,这样下次再运行该程序时,可以很快的启动。随着系统中保留的程序越来越多,内存肯定会出现不足,low memory killer就是在系统内存低于某值时,清除相关的程序,保障系统保持拥有一定数量的空闲内存。

Low memorykiller根据两个原则,进程的重要性和释放这个进程可获取的空闲内存数量,来决定释放的进程。

进程的重要性,由task_struct->signal_struct->oom_adj决定,

Android将程序的重要性分成以下几类,按照重要性依次降低的顺序,每个程序都会有一个oom_adj值,这个值越小,程序越重要,被杀的可能性越低:

除了上述程序重要性分类之外,Android系统还维护着另外一张表minfree用于维护内存警戒值,这两张表构成一个对应关系,两张表在” /sys/module/lowmemorykiller/parameters/”下保存。

adj文件内容如下形如”0,1,2,4,9,15”,minfree文件内容形如”8192,10240,12288,14336,1638,20480”,这样形成的表结构如下:

例如,当系统可用内存小于12384*4K大小时,会开始杀掉oom_adj>=9级别的进程。

进程的内存,通过get_mm_rss获取,在相同的oom_adj下,内存大的,优先被杀。

Ashmem(匿名内存共享):

源码位置:kernel/mm/ashmem.c

为进程间提供提供大块共享内存,同时为内核提供回收和管理这个内存的机制。

相比于malloc和anonymous/namedmmap等传统的内存分配机制,其优势是通过内核驱动提供了辅助内核的内存回收算法机制(pin/unpin)。什么是pin和unpin呢?具体来讲,就是当你使用Ashmem分配了一块内存,但是其中某些部分却不会被使用时,那么就可以将这块内存unpin掉。

unpin后,内核可以将它对应的物理页面回收,以作他用。你也不用担心进程无法对unpin掉的内存进行再次访问,因为回收后的内存还可以再次被获得(通过缺页handler),因为unpin操作并不会改变已经 mmap的地址空间。

AndroidPMEM/ION内存管理器:

源码位置:drivers/misc/pmem.c

AndroidPmem是为了实现共享大尺寸连续物理内存而开发的一种机制,该机制对dsp,gpu等部件非常有用。Pmem相当于把系统内存划分出一部分单独管理,即不被linux mm管理,实际上linux mm根本看不到这段内存。

Pmem和Ashmem都通过mmap来实现共享内存,其区别在于Pmem的共享区域是一段连续的物理内存,而Ashmem的共享区域在虚拟空间是连续的,物理内存却不一定连续。dsp和某些设备只能工作在连续的物理内存上,这样cpu与dsp之间的通信就需要通过Pmem来实现。

ION是google在Android4.0ICS为了解决内存碎片管理而引入的通用内存管理器,它会更加融合kernel。目前QCOM MSM, NVDIA Tegra, TI OMAP, MRVL PXA都用ION替换PMEM。

ION 定义了四种不同的heap,实现不同的内存分配策略。

AndroidNative内存和Dalvik内存管理:

Native进程是采用C/C++实现,不包含dalvik实例的进程,/system/bin/目录下面的程序文件运行后都是以native进程形式存在的,如/system/bin/surfaceflinger、/system/bin/rild、procrank等就是native进程,地址空间结构如下:

java进程是Android中运行于dalvik虚拟机之上的进程。dalvik虚拟机的宿主进程由fork()系统调用创建,所以每一个java进程都是存在于一个native进程中,因此,java进程的内存分配比native进程复杂,因为进程中存在一个虚拟机实例。Android系统中的应用程序基本都是java进程,如桌面、电话、联系人、状态栏等等,进程结构如下:

Stack空间(进栈和出栈)由操作系统控制,其中主要存储函数地址、函数参数、局部变量等等,所以Stack空间不需要很大,一般为几MB大小。

Heap空间的使用由程序员控制,程序员可以使用malloc、new、free、delete等函数调用来操作这片地址空间。Heap为程序完成各种复杂任务提供内存空间,所以空间比较大,一般为几百MB到几GB。正是因为Heap空间由程序员管理,所以容易出现使用不当导致严重问题。

进程空间中的heap空间是我们需要重点关注的。heap空间完全由程序员控制,我们使用的malloc、C++ new和java new所申请的空间都是heap空间, C/C++申请的内存空间在native heap中,而java申请的内存空间则在dalvik heap中。

进程的内存空间只是虚拟内存(或者叫作逻辑内存),而程序的运行需要的是实实在在的内存,即物理内存(RAM)。在必要时,操作系统会将程序运行中申请的内存(虚拟内存)映射到RAM,让进程能够使用物理内存。

RAM作为进程运行不可或缺的资源,对系统性能和稳定性有着决定性影响。另外,RAM的一部分被操作系统留作他用,比如显存等等,内存映射和显存等都是由操作系统控制,我们也不必过多地关注它,进程所操作的空间都是虚拟地址空间,无法直接操作RAM。示意图如下:

Android系统对dalvik的vm heapsize作了硬性限制,当java进程申请的java空间超过阈值时,就会抛出OOM异常,在/system/build.prop中有三项可以配置相关信息。

dalvik.vm.heapstartsize:堆分配的初始大小,调整这个值会影响到应用的流畅性和整体ram消耗。这个值越小,系统ram消耗越慢,但是由于初始值较小,一些较大的应用需要扩张这个堆,从而引发gc和堆调整的策略,会应用反应更慢。相反,这个值越大系统ram消耗越快,但是程序更流畅。

dalvik.vm.heapgrowthlimit:受控情况下的极限堆(仅仅针对dalvik堆,不包括native堆)大小,dvm heap是可增长的,但是正常情况下dvm heap的大小是不会超过dalvik.vm.heapgrowthlimit的值(非正常情况下面会详细说明)。这个值控制那些受控应用的极限堆大小,如果受控的应用dvm heap size超过该值,则将引发oom(out of memory)。

dalvik.vm.heapsize:不受控情况下的极限堆大小,这个就是堆的最大值。不管它是不是受控的。这个值会影响非受控应用的dalvikheap size。一旦dalvik heap size超过这个值,直接引发oom。

JVM垃圾回收机制:

JVM的垃圾原理是这样的,它把对象分为年轻代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的垃圾回收算法。

年轻代(Young):年轻代分为三个区,一个eden区,两个Survivor区。程序中生成的大部分新的对象都在Eden区中,当Eden区满时,还存活的对象将被复制到其中一个Survivor区,当此Survivor区的对象占用空间满了时,此区存活的对象又被复制到另外一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到年老代。

年老代(Tenured)年老代存放的是上面年轻代复制过来的对象,也就是在年轻代中还存活的对象,并且区满了复制过来的。一般来说,年老代中的对象生命周期都比较长。

持久代(Perm)用于存放静态的类和方法,持久代对垃圾回收没有显著的影响。

Android内存分析工具:

         内存监控工具DDMS:

Ddms可以在eclipse中安装对应的插件,同时在androidsdk的tools文件夹也有同样的工具,并且功能比eclipse插件更完备。

切换到eclipse的ddms视图后,从设备中选择要监控的进程(手机需要开启usb调试,被监控应用的manifest中android:debuggable应该为true)

如下图操作,我们主要关注dataobject类型的total size数据在使用过程中是否出现异常的数据波动。

Eclipse MAT插件:

Mat是eclipse的一个插件,安装完成之后,在ddms试图下,同时在左侧设备试图上方选择“Update Heap”和“Dump HPROF file”按钮,在弹出的窗口中选择“Leak Suspects Report”并finish,即可出现下面的结果试图:

进入leaksuspects之后,就能列出所有可能有泄漏的地方以及代码片段

Adb shell的dumpsys meminfo命令:

Adbshell的cat命令:

应用内存分配跟踪工具Allocation tracker:

同样该功能用到ddms ,只是里面提供的一个子功能而已,能够知道所有对象的分配是在代码的哪个类,哪个文件的哪一行。

AndroidOOM的常见原因:

非静态内部类的静态实例容易造成内存泄漏

activity使用静态成员

使用handler时的内存问题

注册某个对象后未反注册

集合中对象没清理造成的内存泄露

资源对象没关闭造成的内存泄露

一些不良代码成内存压力:Bitmap使用不当;构造Adapter时,没有使用缓存的 convertView;在经常调用的方法中创建对象(例如循环)

参考资料:

Androidmemory fundamentals

http://www.slideshare.net/tarasleskiv/android-memory-fundamentals?qid=c8462372-7470-4459-a76c-552c678724c0&v=qf1&b=&from_search=2

Forensic Memory Analysis of Android‘sDalvik Virtual Machine

http://www.slideshare.net/SOURCEConference/forensic-memory-analysis-of-androids-dalvik-virtual-machine?qid=c8462372-7470-4459-a76c-552c678724c0&v=qf1&b=&from_search=6

Memory management for_android_apps

http://www.slideshare.net/shaobin0604/memory-management-forandroidapps?qid=c8462372-7470-4459-a76c-552c678724c0&v=qf1&b=&from_search=11

android内存管理机制分析

http://www.doc88.com/p-992213371842.html

Android 操作系统的内存回收机制

http://blog.jobbole.com/25169/

Android系统匿名共享内存(AnonymousShared Memory)C++调用接口分析

http://blog.csdn.net/luoshengyang/article/details/6939890

Android系统匿名共享内存Ashmem(AnonymousShared Memory)简要介绍和学习计划 - 老罗的Android之旅 - 博客频道 - CSDN.NET

http://blog.csdn.net/luoshengyang/article/details/6651971

程序源代码分析 - 老罗的Android之旅 - 博客频道 - CSDN.NET

http://blog.csdn.net/luoshengyang/article/details/6664554

Android系统匿名共享内存Ashmem(AnonymousShared Memory)在进程间共享的原理分析 - 老罗的Android之旅 - 博客频道 - CSDN.NET

http://blog.csdn.net/luoshengyang/article/details/6666491

Windows内存与进程管理器底层分析

http://www.cnblogs.com/zudn/archive/2010/12/29/1920593.html

什么是内存直接映像技术?它有何特点?

http://zhidao.baidu.com/link?url=e8NFxuOaY9UsOxKGklWmTR20-gpDGy48eE1SerGNCjAYbg3Xj-Fp0pqBSAKFy_AEjyKQOWmx3QHGn4ldWgec0M1wxBowDOT59Bua2O0DjZC

Mysteries of Windows Memory ManagementRevealed

http://media.ch9.ms/teched/na/2011/ppt/WCL406.pptx

全面介绍Windows内存管理机制及C++内存分配实例

http://blog.csdn.net/yeming81/article/details/2046193

技术内幕:Android对Linux内核的增强

http://tech.it168.com/a2011/0805/1228/000001228471_all.shtml

android内存管理了解_百度文库

http://wenku.baidu.com/link?url=bGaPQbl7u1_JmKSJ5nVBv1dHtvGSXREyv_7PeSt9_FCx20I5oK1EaEgno9d6Ked4Kao92yoP_7X6gOQToylezMwEn-inKnBxb7SAoJ3jH6m

Android low memory killer 详解-tuyer-ChinaUnix博客

http://blog.chinaunix.net/uid-20321537-id-3228776.html

Linux 设备文件简介

http://www.jinbuguo.com/kernel/device_files.html

Explore Android Internals

http://www.slideshare.net/jserv/android-internals-30176596?qid=a3be858d-e483-423c-be0e-a85e0a08fdd6&v=qf1&b=&from_search=4

Inside Android‘s Dalvik VM - NEJUG Nov 2011

http://www.slideshare.net/dougqh/inside-androids-dalvik-vm-nejug-nov-2011?qid=a3be858d-e483-423c-be0e-a85e0a08fdd6&v=qf1&b=&from_search=3

android之ION内存管理器(1)-- 简介

http://blog.csdn.net/crazyjiang/article/details/7927260

Android进程的内存管理分析

http://blog.csdn.net/gemmem/article/details/8920039

Gc in android

http://www.slideshare.net/VikasBalikai/gc-in-android

Android内存泄漏分析及调试

http://blog.csdn.net/gemmem/article/details/13017999

Android OOM介绍及分析方法

http://blog.csdn.net/gemmem/article/details/8964397

时间: 2024-11-08 22:28:14

[Android Memory] Android内存管理、监测剖析的相关文章

Android中的内存管理机制以及正确的使用方式

概述 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面来理解操作系统的内存管理机制. 第一:分配机制.为每一个进程分配一个合理的内存大小,保证每一个进程能够正常的运行,不至于内存不够使用或者每个进程占用太多的内存. 第二:回收机制.在系统内存不足打的时候,需要有一个合理的回收再分配的机制,以保证新的进程可以正常运行.回收的时候就要杀死那些正在占有内存的进程,操

Objective -C Memory Management 内存管理 第一部分

Objective -C Memory Management??内存管理??第一部分 Memory management is part of a more general problem in programming called resource management. 内存管理是资源管理的一部分. Every computer system has finite resources for your program to use. These include memory, open fi

Objective-C Memory Management 内存管理 2

Objective-C Memory Management?内存管理? 2? 2.1 The Rules of Cocoa Memory Management 内存管理规则 (1)When you create an object using new, alloc, or copy, the object has aretain count of 1. You are responsible for sending the object a release or autorelease mess

【转】Android中的内存管理--不错不错,避免使用枚举类型

原文网址:http://android-performance.com/android/2014/02/17/android-manage-memory.html 本文内容翻译自:http://developer.android.com/training/articles/memory.html 随机存取存储器(RAM)再任何软件开发环境中都是宝贵的资源,但是在移动操作系统中,内存资源更为宝贵,使用时也会收到限制.虽然Android的Dalvik虚拟机有运行时的垃圾回收机制,但是这不意味着你的A

Android开发之内存管理

概念 应用的开发离不开存储,存储分为网络.内存.SDCard文件存储以及外部SDCard2文件存储,开发中一定要注意好内存管理以免oom.卡顿等不好的用户体验,同时还要注意变量的回收,避免内存泄漏.下面呢先来了解一些基本的相关专业术语. RAM(random access memory)随机存取存储器即内存 寄存器(Registers):速度最快的存储场所,因为寄存器位于处理器内部,我们在程序中无法控制 栈(Stack):存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 堆

Linux内核之内存管理完全剖析

linux虚拟内存管理功能 ? 大地址空间:? 进程保护:? 内存映射:? 公平的物理内存分配:? 共享虚拟内存.实现结构剖析 (1)内存映射模块(mmap):负责把磁盘文件的逻辑地址映射到虚拟地址,以及把虚拟地址映射到物理地址 (2)交换模块(swap)负责控制内存内容的换入与换出,淘汰最近没访问的页,保留最近访问的页. (3)core(核心内存管理模块):负责内存管理功能. (4)结构特定模块:实现虚拟内存的物理基础 内核空间和用户空间 Linux简化了分段机制,使得虚拟地址跟线性地址一样.

[Android Memory] Android Zipalign zip对齐优化app程序

转载地址:http://www.cnblogs.com/xirihanlin/archive/2010/04/12/1710164.html 参考文章:http://www.cnblogs.com/lee0oo0/archive/2013/06/13/3133833.html Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化.在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率.因此,这种方式能够让应用程序和整个系

[Android Memory] Android性能测试小工具Emmagee

转载:http://blog.csdn.net/anlegor/article/details/22895993 Emmagee是网易杭州QA团队开发的用于测试指定android应用性能的小工具.该工具的优势在于如同windows系统性能监视器类似,它提供的是数据采集的功能,而行为则基于用户真实的应用操作. 在使用上几乎近似不用任何教材即可上手,我们以360手机卫士为例,查看启动,扫描.清理过程中资源消耗的变化. 首先启动Emmagee,设置采集频率为1秒,从列表中选择360安全卫士,开始测试

内存管理机制剖析

在.NET Framework中,内存中的资源(即所有二进制信息的集合)分为"托管资源"和"非托管资源".托管资源必须接受.NET Framework的CLR(通用语言运行时)的管理(诸如内存类型安全性检查),而非托管资源则不必接受.NET Framework的CLR管理.  (了解更多区别请参阅.NET Framework或C#的高级编程资料) 托管资源在.NET Framework中又分别存放在两种地方: "堆栈"和"托管堆&quo