概述

在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在是少的可怜。这样就需要我们在开发过程中要时刻注意。不要因为自己的代码问题而造成OOM错误。

JAVA的内存管理

大家都知道,android应用层是由java开发的,android的davlik虚拟机与jvm也类似,只不过它是基于寄存器的。因此要了解android的内存管理就必须得了解java的内存分配和垃圾回收机制。

在java中,是通过new关键字来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,工程师在开发的过程中,不需要显式的去管理内存。但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVM的OOM。因此,java工程师还是有必要了解JAVA的内存分配和垃圾回收机制。

  1. 内存结构

上面这张图是JVM的结构图,它主要四个部分组成:Class Loader子系统和执行引擎,运行时方法区和本地方法区,我们主要来看下RUNTIME DATA AREA区,也就是我们常说的JVM内存。从图中可以看出,RUNTIMEDATA AREA区主要由5个部分组成:

  • Method Area:被装载的class的元信息存储在Method Area中,它是线程共享的
  • Heap(堆):一个java虚拟机实例中只存在一个堆空间,存放一些对象信息,它是线程共享的
  • Java栈: java虚拟机直接对java栈进行两种操作,以帧为单位的压栈和出栈(非线程共享)
  • 程序计数器(非线程共享)
  • 本地方法栈(非线程共享)
  1. JVM的垃圾回收(GC)

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

  • 年轻代(Young)

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

  • 年老代(Tenured)

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

  • 持久代(Perm)

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

Android中内存泄露监测

在了解了JVM的内存管理后,我们再回过头来看看,在android中应该怎样来监测内存,从而看在应用中是否存在内存分配和垃圾回收问题而造成内存泄露情况。

在android中,有一个相对来说还不错的工具,可以用来监测内存是否存在泄露情况:DDMS—Heap

使用方法比较简单:

  • 选择DDMS视图,并打开Devices视图和Heap视图
  • 点击选择要监控的进程,比如:上图中我选择的是system_process
  • 选中Devices视图界面上的"update heap" 图标
  • 点击Heap视图中的"Cause GC" 按钮(相当于向虚拟机发送了一次GC请求的操作)

在Heap视图中选择想要监控的Type,一般我们会观察dataobject的 total size的变化,正常情况下total size的值会稳定在一个有限的范围内,也就说程序中的代码良好,没有造成程序中的对象不被回收的情况。如果代码中存在没有释放对象引用的情况,那么data object的total size在每次GC之后都不会有明显的回落,随着操作次数的增加而total size也在不断的增加。(说明:选择好data object后,不断的操作应用,这样才可以看出total size的变化)。如果totalsize确实是在不断增加而没有回落,说明程序中有没有被释放的资源引用。那么我们应该怎么来定位呢?

Android中内存泄露定位

Mat(memory analyzer tools)是我们常用的用来定位内存泄露的工具,如果你使用ADT,并且安装了MAT的eclipse插件,你需要做的是进入DDMS视图的Devices视图:

点击"dump HPROF file"按钮,然后使用MAT分析下载下来的文件。

下面列出了存在的问题,点击detail进去,会列出详细的,可能会存在问题的代码:

关于MAT的使用可以参考:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html

这位兄弟写的比较详细。

总结

不管是java还是android,都应该了解内存分配和垃圾回收机制,工程师要做到写的代码中没有bad code很难,关键是在出现问题的时候该怎么去排查。

Android 之 内存管理-查看内存泄露(三)的更多相关文章

  1. Linux进程管理——查看内存的工具

    Linux进程管理——查看内存的工具 一查看内存的工具vmstat vmstat命令:虚拟内存信息vmstat [options] [delay [count]]vmstat 2 5 [root@ce ...

  2. SAP专家培训之Netweaver ABAP内存管理和内存调优最佳实践

    培训者:SAP成都研究院开发人员Jerry Wang 1. Understanding Memory Objects in ABAP Note1: DATA itab WITH HEADER LINE ...

  3. Delphi的内存管理及内存泄露问题 FastMM4

    这几天因为一个程序长时间运行出现比较严重的内存泄露问题,开始关注了一下内存管理方面的东西,以前也注意内存管理,创建了对象及时释放,但总有忘了处理的情况. 在Delphi中没有自动回收机制,所以一定要及 ...

  4. Java的内存管理与内存泄露

    作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存 ...

  5. Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)

    勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分享了JVM及其启动流程,今天介绍一下JVM内部的一些区域,以及具体的区域在运行 ...

  6. Android内存优化6 了解Android是如何管理App内存

    1, Dalvik & ART Android在4.4之前一直使用的Dalvik虚拟机作为App的运行VM的, 4.4中引入了ART作为开发者备选, 5.0起正式将ART作为默认VM了. 我们 ...

  7. Android系统如何管理自己内存的?

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 机缘巧合写下这篇博客,作为个人工作经验的总结,不足之处,随后补上. 安卓是基于Linux2.6内核的 ...

  8. [C]内存管理、内存泄露、堆栈

    原文地址:https://www.cnblogs.com/youthshouting/p/4280543.html,转载请注明源地址. 1.内存分配区间:         对于一个C语言程序而言,内存 ...

  9. 浅谈C语言内存管理、内存泄露、堆栈

    1.内存分配区间:         对于一个C语言程序而言,内存空间主要由五个部分组成:代码段(.text).数据段(.data).静态区(.BSS).堆和栈组成.         BSS段:BSS段 ...

随机推荐

  1. HTML5如何重塑O2O用户体验

    低频次垂直O2O服务应该继续开发原生APP吗?大家有没有发现做一个APP的推广成本和获取用户的成本越来越高?第二,用户安装APP之后,用户并不是经常点击使用APP的,那这是为什么?数据表明90%的O2 ...

  2. 使用OpenXml操作Excel,以下方法用于在添加列时修改Cell的CellReference属性。

    以下方法实现了递增Excel中单元格的CellReference的功能,只支持两位字母. public static string CellReferenceIncrement(string cell ...

  3. clients(PV操作共享内核内存进行输入输出分屏) - server(进程间通信)模型实现

    1.拓扑结构 2.PV操作共享内核内存进行输入输出分屏 (1) int semop(int semid,struct sembuf *sops,size_t nsops): 功能描述 操作一个或一组信 ...

  4. String Subtraction

    Given two strings S1 and S2, S = S1 - S2 is defined to be the remaining string after taking all the ...

  5. 【转】用perl写的单位电脑信息采集程序

    perl,后来我又改过了增加了一些交互和数据库检测的功能.主要用于收集ip.mac.姓名.房间,后来又加入了维修记录的功能.服务器端接受数据并存入数据库中. 代码如下: 主要用于收集ip.mac.姓名 ...

  6. 【Passport】微软过时的技术

    虽然已过时,没来得及体验,摘录一段别人的文章,假装对passport的了解 微软在过去的身份验证服务上,一直采用的Passport验证,但已经是N年前推出来的一个软件架构,当然也被软件界很多地方采用到 ...

  7. C# list 筛选FindAll

    例如:参数a.list b.ModelId:根据ModelId参数进行筛选 /// <summary> /// 根据ModelId筛选查询出对应的数据 /// </summary&g ...

  8. 为什么dubbo使用ZkClient作为zookeeper的客户端

    本文内容并非原创,使用资料均来自互联网. dubbo使用了zkClient而不是使用zookeeper本身的客户端与zookeeper进行交互,为什么呢? 先看看zookeeper本身自带的客户端的问 ...

  9. apache与nginx日志文件的区别(转载)

    apache与nginx日志文件的区别 转载:http://www.xfcodes.com/apache/log/3270.htm 导读:apache与nginx日志文件的区别,在apache与ngi ...

  10. java小提示:标示符常见命名规则、常用ASCII

    标示符常见命名规则: A:包:全部小写B:类或者接口:首字母大写:StudentC:方法或者接口:首字母小写,第二个单词开始开始,每个单词首字母大写:studentAgeD:常量:全部大写,多个单词之 ...