Android 内存管理 &Memory Leak & OOM 分析
转载博客:http://blog.csdn.net/vshuang/article/details/39647167
1、Android 进程管理&内存
同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足时,Android会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要性,Android会首先停止那些不重要的进程。按照重要性从高到低一共有五个级别就是我们常说的:前台进程、可见进程、服务进程、后台进程、空进程。
2、单个应用可用的最大内存
dalvik.vm.heapsize=384m//heapsize参数表示单个进程可用的最大内存,但如果存在heapgrowthlimit参数,则以heapgrowthlimit为准.
heapsize表示不受控情况下的极限堆,表示单个虚拟机或单个进程可用的最大内存。而android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机(这样设计就会在单个程序崩溃的情况下不会导致整个系统的崩溃)。
注意:在设置了heapgrowthlimit的情况下,单个进程可用最大内存为heapgrowthlimit值。在android开发中,如果要使用大堆,需要在manifest中指定android:largeHeap为true,这样dvm heap最大可达heapsize。
不同设备,这些个值可以不一样。一般地,厂家针对设备的配置情况都会适当的修改/system/build.prop文件来调高这个值。随着设备硬件性能的不断提升,从最早的16M限制(G1手机)到后来的24m,32m,64m等,都遵循Android框架对每个应用的最小内存大小限制,参考http://source.android.com/compatibility/downloads.html 3.7节。
通过代码查看每个进程可用的最大内存,即heapgrowthlimit值:
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();//64,以m为单位
3、为什么会内存泄露(Memory Leak)?
android通过android虚拟机来管理内存,程序员只管申请内存创建对象,创建完不再需要关心怎么释放对象内存,一切由虚拟机帮你搞定,然而虚拟机回收对象是有条件的。这里简单叙述下java内存管理机制,java虚拟机维护着一张当前对象关系的object tree,当GC发生时,虚拟机会从GC Roots 开始去扫描当前的对象树,发现通过任何reference chain(引用链)无法访问某个对象的时候,该对象即被回收。名词GC Roots正是分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC Roots),所以GC Roots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是一个在current thread(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或者是线程自身或者是system class loader(系统类加载器)加载的类以及native code(本地代码)保留的活动对象。所以GC Roots是分析对象为何还存活于内存中的利器。知道了什么样的对象GC才会回收后,再来学习下对象引用都包含哪些吧。
Java中包含4种对象引用:
强引用: 通常我们编写的代码都是Strong Ref,eg :Person person = new Person("sunny");不管系统资源有多紧张,强引用的对象都绝对不会被回收,即使他以后不再用到。
软引用:只要有足够的内存,就一直保持对象。一般可用来实现缓存,通过java.lang.r.efSoftReference类实现。内存非常紧张的时候会被回收,其他时候不会被回收,所以在使用之前需要判空,从而判断当前时候已经被回收了。
弱引用:通过WeakReference类实现,eg : WeakReference p = new WeakReference(new Person("Rain"));不管内存是否足够,系统垃圾回收时必定会回收。
虚引用:不能单独使用,主要是用于追踪对象被垃圾回收的状态。通过PhantomReference类和引用队列ReferenceQueue类联合使用实现。
我们可能还需要了解shallow size、retained size概念,简单来说,Shallow size就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。在32位系统上,对象头占用8字节,int占用4字节,不管成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为null它始终占用4字节。故此,对于String对象实例来说,它有三个int成员(34=12字节)、一个char[]成员(14=4字节)以及一个对象头(8字节),总共34 +14+8=24字节。根据这一原则,对String a=”rosen jiang”来说,实例a的shallow size也是24字节。Retained size是该对象自己的shallow size,加上只能从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。为了更好的理解retained size,我们来看个例子。
图1
假设内存中对象之间的引用关系可以看成图1的方式,从图中可以看到 GC正是reference chain的起点。从obj1入手,上图中蓝色节点代表仅仅只有通过obj1才能直接或间接访问的对象。因为可以通过GC Roots访问,所以左图的obj3不是蓝色节点;而在右图却是蓝色,因为它已经被包含在retained集合内。所以对于左图,obj1的retained size是obj1、obj2、obj4的shallow size总和;右图的retained size是obj1、obj2、obj3、obj4的shallow size总和。
相信了有以上的这些基础概念,我们应该对java内存管理有了一个初步的了解。
4、为什么会发生OOM(Out Of Memory)?
5、常见的MemoryLeak分析
后来看到了更多的MemoryLeak相关的知识,有了更多的实践经验,
Android 内存管理 &Memory Leak & OOM 分析的更多相关文章
- Android 内存管理 &Memory Leak & OOM 分析
1.Android 流程管理&内存 Android主要应用在嵌入式设备其中.而嵌入式设备因为一些众所周知的条件限制,通常都不会有非常高的配置,特别是内存是比較有限的. 假设我们编写的代 码其中 ...
- Android 内存优化 (防Memory Leak)
在之前的 Android 内存管理 &Memory Leak & OOM 分析 中,说到了Android的内存管理相关的原理,也能了解到Android Memory Leak 和 ...
- [Android Memory] Android内存管理、监测剖析
转载自:http://blog.csdn.net/anlegor/article/details/23398785 Android内存管理机制: Android内存管理主要有:LowMemory Ki ...
- Android内存管理机制之一:low memory killer
转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...
- java 基础知识学习 内存泄露(memory leak) VS 内存溢出(out of memory)以及内存管理
内存泄露(memory leak) VS 内存溢出(out of memory) 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory ...
- Android 内存管理分析(四)
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...
- 浅谈Android内存管理
最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误,仅仅知道这些,还是无法从整体上理解内存管理,对培养系统优 ...
- 内存泄漏(Memory Leak)
内存泄露检测工具Valgrind 内存泄露简介 回到顶部 什么是内存泄漏 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因,程序未释放或无法释放,造成系统内存的浪费,导致 ...
- Android——内存管理基础
内存收集概念 内存垃圾收集器(garbage collector) 概念:自定内存管理. 功能:分配内存.保证所有被引用的对象还在内存中.可以释放在运行的代码中不再引用的对象的内存. 垃圾收集器避免了 ...
随机推荐
- Shader实例:溶解效果(Dissolve)
效果: 图左:一道金光闪过,瞬间灰飞烟灭 图右:燃烧效果,先过渡到黄色,然后渐渐过渡到黑色,最后消失殆尽. 这是游戏中常见的效果,各位可以想想自己玩过的游戏. 手头正在玩的,梦三国手游,死亡的时候就是 ...
- MIME(多用途互联网邮件扩展类型)
MIME对照表 百度百科 MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型.(百度百科).是设定某种扩展名的文件用一种应用程序来打开的方式 ...
- photoshop
photoshop裁剪 photoshop裁剪快捷键是C键: 使用photoshop裁剪工具裁切出图片的方法: 选择好所需要的图片,右键保存到本地计算机' 在photoshop中打开这张图片(文件/打 ...
- Apache服务器在80端口配置多域名虚拟主机的方法
我们在配置一台服务器的时候,如果只运行一个站点,往往过于浪费资源.Nginx和Apache都可以通过配置虚拟主机实现多站点.配置虚拟主机的方式主要有两种,一种是多个不同端口对应的多个虚拟主机站点,一种 ...
- $.each ---- 跳出当前的循环
有些朋友可能会以为在jquery跳出循环可以直接使用continue和break了,但是使用之后没有效果,因为在jquery中没有这两条命令.后来上网查了下,得到了结果:return false;—— ...
- 用c#创建支持多语言的WinForm应用程序
实现多语言的方法可能有使用资源文件,或者配置xml两种方法吧.没时间研究过多,学习了一下使用资源文件的方法,成功了. 在.net2.0 中,m$ 为我们提供了一种简单方便的方法, 使用资源文件 1.新 ...
- JQuery 获取父级元素、同级元素、子元素等
例: <div> <div id="div_1">这是内容1</div> <div id="div_2">这是内 ...
- opencv算法学习
1.改变图像的亮度和对比度: 算法介绍:对每一点像素值的r,g,b,值进行乘法和加法的运算. 代码使用: ; y < image.rows; y++ ) { ; x < image.col ...
- java学习之面向对象(2)
在描述事物的时候,该事物已存在就具备的一些内容,这是我们就可以把它们都定义在构造函数中,那么什么是构造函数呢? 构造函数就是构建创造对象时调用的函数,它可以给对象进行初始化.构造函数与类名相同,第一个 ...
- SQL Server2016 新功能实时查询统计信息
SQL Server2016 新功能实时查询统计信息 很多时候有这样的场景,开发抱怨DBA没有调优好数据库,DBA抱怨开发写的程序代码差,因此,DBA和开发都成为了死对头,无法真正排查问题. DBA只 ...