文档章节

Android 之 内存管理

 等待流星
发布于 2014/03/08 10:54
字数 1406
阅读 62
收藏 13

概述

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

JAVA的内存管理

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

java中,是通过new关键字来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,工程师在开发的过程中,不需要显式的去管理内存。但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVMOOM。因此,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中,有一个相对来说还不错的工具,可以用来监测内存是否存在泄露情况:DDMSHeap


使用方法比较简单:

  • 选择DDMS视图,并打开Devices视图和Heap视图

  • 点击选择要监控的进程,比如:上图中我选择的是system_process

  • 选中Devices视图界面上的"update heap" 图标

  • 点击Heap视图中的"Cause GC" 按钮(相当于向虚拟机发送了一次GC请求的操作)

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

Android中内存泄露定位

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


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


 

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

 

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

这位兄弟写的比较详细。

总结

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


本文转载自:http://blog.csdn.net/xieqibao/article/details/6707519

共有 人打赏支持
粉丝 5
博文 78
码字总数 10995
作品 0
崇明
私信 提问
Android内存管理、监测剖析

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

Jerikc
2015/01/14
0
0
Linux与Android的关系

大家都知道Android是基于Linux内核的操作系统,也曾经和Linux基金会因为内核问题产生过分歧,本文将开始对Android的内核进行剖析,主要介绍Android和Linux之间的关系,后续还会讲到Android系...

开心303
2011/08/03
0
0
Android安全模型之Android安全机制(内存管理)

Ashmem匿名共享内存 Android的匿名共享内存(Ashmem)机制基于Linux内核的共享内存,但是Ashmem与cache shrinker关联起来,增加了内存回收算法的注册接口,因此Linux内存管理系统将不再使用内...

柳哥
2014/12/02
0
0
Android系统源码分析团体项目BeesAndroid正式上线啦

嗨,BeesAndroid开源技术小组正式成立啦,Bees,即蜜蜂,取义分享、合作与奉献的意思,这也是BeesAndroid小组的宗旨,我们第一个团体项目BeesAndroid也于2018年3月6日同步上线,该项目的前 ...

郭孝星
03/08
0
0
Android各版本间API的差异 - Bitmap

概述 Bitmap在API Level 1中就已经有了, 只不过随着SDK更新, Google对它的一些内外部接口/实现进行了一些优化或者调整, 主要是内存资源的管理方面. 差异 内存资源回收: Android 2.3(API Lev...

有初啊
2014/01/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

我的Linux系统九阴真经

我的Linux系统九阴真经 在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行...

linuxCool
38分钟前
9
0
Python程序员需要知道的30个技巧

1 直接交换两个数字位置 1x, y = 10, 202print(x, y)3x, y = y, x4print(x, y)5#1 (10, 20)6#2 (20, 10) 2 比较运算符的链接 1n = 102result = 1 < n < 203print(result)4# True5result = 1 ......

糖宝lsh
39分钟前
4
0
[LintCode] Linked List Cycle(带环链表)

描述 给定一个链表,判断它是否有环。 样例 给出 -21->10->4->5, tail connects to node index 1,返回 true。 这里解释下,题目的意思,在英文原题中,tail connects to node index 1 表示的...

honeymose
50分钟前
7
0
Android :报错Your project path contains non-ASCII characters.

报错内容如下 Your project path contains non-ASCII characters. This will most likely cause the build to fail on Windows. Please move your project to a different directory. See ht......

lanyu96
今天
6
0
Nginx平滑添加模块

Nginx已经编译安装并运行了一段时间, 然后某一天, 发现需要用到某个模块但当初没有编译, 这个时候怎么办呢? 卸载重新安装肯定可以的, 如果Nginx版本没有变更的话, 则有一个相对平滑的方法来添...

老菜鸟0217
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部