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

1, Dalvik & ART

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

我们首先来简单了解下二者:

1.1 Dalvik

如果只是想简单了解, 个人觉得百度百科上这个Dalvik的介绍基本就满足要求了.

如果大家想深入, 可以看下老罗的Android之旅Dalvik的相关博文, 从代码层面上分析了Dalvik的启动, 运行机制等. 值得一看.

需要说明的是, Dalvik采用的是JIT技术, 在应用程序启动时, JIT通过进行连续的性能分析来优化程序代码的执行, 在程序运行的过程中, Dalvik在不断的进行将字节码编译成机器码的工作.

1.2 ART

ART 取自 Android RunTime. Android用其取代Dalvik, 主要目的就是为了提升运行性能. 所以, ART相比Dalvik有几个关键的提升:

引入AOT(ahead-of-time)预编译技术

在安装apk的过程中, ART会使用dex2oat程序所有的字节码预编译成了机器码. 应用程序运行过程中无需进行实时的编译工作, 只需要进行直接调用. 故而提高了应用程序的运行效率.

GC效率

  • 由原来的两次GC暂停减少为一次.
  • 以较少的GC时间回收最近分配的, 短命的对象.
  • 提升GC工程学, 使并发GC更及时.
  • 压缩GC, 以减少后台内存使用和内存碎片.

开发和调试

  • 支持内存/方法执行的采样分析.
  • 支持更多的调试技.
  • 在Crash report中提供更多信息.

2, Android的内存管理方式

ART和Dalvik都是使用pagingmemory-mapping(mmapping)来管理内存的. 这就意味着, 任何被分配的内存都会持续存在, 唯一的释放这块内存的方式就是释放对象引用(让对象GC Root不可达), 故而让GC程序来回收内存.

2.1 App的内存分配和回收

对于每个App进程来说, Heap内存被限制在一个虚拟的内存区间内. 且定义了逻辑上的使用的Heap Size, 这个Heap Size在系统限制的最大值之内是随着应用的使用情况而变化的.

Heap内存的逻辑大小和实际物理内存的大小是不相同的. 后面我们在使用Memory Monitor等内存分析工具分析内存时, 会看到一个叫做Proportional Set Size (PSS)的值, 这个值才是系统认为的你的App所占用的物理内存大小.

这个PSS值也就是实际物理内存大小, 统计包括了你的应用进程所占用的内存大小, 和共享内存中占用的内存大小(比例分配方式计算).

Android VM不会压缩Heap内存的逻辑大小, 故而无法通过碎片整理的方式来释放Heap空间, 而只能通过回收Heap尾部的空内存块来压缩逻辑内存大小.

这时, 我们的GC就出场了, GC之后, VM会遍历Heap找到不被使用的pages, 通过madvise函数将其返回给内核, 从而释放这块被逻辑Heap使用的物理内存.

2.2 App内存限制

Android是一个多任务系统, 为了保证多任务的运行, Android给每个App可使用的Heap大小设定了一个限定值.

这个值是系统设置的prop值, 系统编译时内置的, 保存在system/build.prop中. 一般国内的手机厂商都会做修改, 根据手机配置不同而不同, 可以通过如下命令查看:

$ adb shell
[email protected]:/ $ cat /system/build.prop

以手头的Huawei 荣耀6为例, heap size相关的prop如下:

dalvik.vm.heapstartsize=8m
dalvik.vm.heapgrowthlimit=192m
dalvik.vm.heapsize=512m
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=2m
dalvik.vm.heapmaxfree=8m

其中:

dalvik.vm.heapstartsize

-- App启动后, 系统分配给它的Heap初始大小. 随着App使用可增加.

dalvik.vm.heapgrowthlimit

-- 默认情况下, App可使用的Heap的最大值, 超过这个值就会产生OOM.

dalvik.vm.heapsize

-- 如果App的manifest文件中配置了largeHeap属性, 如下.则App可使用的Heap的最大值为此项设定值.

<application
    android:largeHeap="true">
    ...
</application>

dalvik.vm.heaptargetutilization

-- 当前理想的堆内存利用率. GC后, Dalvik的Heap内存会进行相应的调整, 调整到当前存活的对象的大小和 / Heap大小 接近这个选项的值, 即这里的0.75. 注意, 这只是一个参考值.

dalvik.vm.heapminfree

-- 单次Heap内存调整的最小值.

dalvik.vm.heapmaxfree

-- 单次Heap内存调整的最大值.

也可以直接使用getprop查看单项prop:

$ adb shell getprop dalvik.vm.heapsize
512m

2.3 切换App时的内存管理机制

Android的进程级别

Android 系统会尽可能长时间地保持应用进程, 但为了新建进程或运行更重要的进程, 最终需要清除旧进程来回收内存. 为了确定保留或终止哪些进程, 系统会根据进程中正在运行的组件以及这些组件的状态, 将每个进程设定了一个重要级别. 必要时, 系统会首先消除重要性最低的进程, 然后是重要性略低的进程, 依此类推, 以回收系统资源.

依据重要程度从大到小依次分为5级:

前台进程

用户当前操作所必需的进程. 如果一个进程满足以下任一条件, 即视为前台进程:

  • 托管用户正在交互的 Activity(已调用 Activity 的 onResume() 方法)
  • 托管某个 Service,后者绑定到用户正在交互的 Activity
  • 托管正在“前台”运行的 Service(服务已调用 startForeground())
  • 托管正执行一个生命周期回调的 * Service(onCreate()、onStart() 或 onDestroy())
  • 托管正执行其 onReceive() 方法的 BroadcastReceiver

只有在内在不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。 此时,设备往往已达到内存分页状态,因此需要终止一些前台进程来确保用户界面正常响应。

可见进程

没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。 如果一个进程满足以下任一条件,即视为可见进程:

  • 托管不在前台、但仍对用户可见的 Activity(已调用其 onPause() 方法)。例如,如果前台 Activity 启动了一个对话框,允许在其后显示上一 Activity,则有可能会发生这种情况
  • 托管绑定到可见(或前台)Activity 的 Service

    可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。

服务进程

正在运行已使用 startService() 方法启动的服务且不属于上述两个更高类别进程的进程。尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

后台进程

包含目前对用户不可见的 Activity 的进程(已调用 Activity 的 onStop() 方法)。这些进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在 LRU (最近最少使用)列表中,以确保包含用户最近查看的 Activity 的进程最后一个被终止。如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态。

空进程

不含任何活动应用组件的进程。保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。

切换App的内存管理

当用户切换App时, 被切换到后台的App所使用的内存并未因此删除, 该App进程被缓存到一个LRU缓存中, 以便用户切换回来时, 能更快的启动App, 让多任务更流畅.

但是, 当系统内存不够用的时候, 就会根据LRU特性, 以及上面说到的进程级别(同时也会考虑该App进程占用的内存大小)来决定杀死哪些进程, 来回收内存, 以便执行当前任务.

所以, 如果我们为了不要让系统kill掉我们的App, 可以从进程级别, 内存消耗量等几个方面进行优化.

结语

本文加上GC那些事儿, 我们讲了两篇的理论知识, 相信大家对Android的内存管理有了个大体的了解, 后面将介绍一些内存分析工具以及使用, 结合实际来说明怎么分析内存问题.

作者:anly_jun
链接:https://www.jianshu.com/p/4ad716c72c12
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/ldq2016/p/8472239.html

时间: 2024-08-28 08:46:16

Android内存优化1 了解Android是如何管理App内存的相关文章

Android性能优化:阿里、腾讯等关于内存泄露的知识都在这里了!

建议收藏,不然就找不到了!!! 前言 在 Android 中,内存泄露的现象十分常见:而内存泄露导致的后果会使得应用Crash本文 全面介绍了内存泄露的本质.原因 & 解决方案,最终提供一些常见的内存泄露分析工具,希望你们会喜欢. 目录 1. 简介 即 ML (Memory Leak)指 程序在申请内存后,当该内存不需再使用 但 却无法被释放 & 归还给 程序的现象 2. 对应用程序的影响 容易使得应用程序发生内存溢出,即 OOM内存溢出 简介: 3. 发生内存泄露的本质原因 具体描述 特

【Java/Android性能优化1】Android性能调优

本文参考:http://www.trinea.cn/android/android-performance-demo/ 本文主要分享自己在appstore项目中的性能调优点,包括同步改异步.缓存.Layout优化.数据库优化.算法优化.延迟执行等. 一.性能瓶颈点 整个页面主要由6个Page的ViewPager,每个Page为一个GridView,GridView一屏大概显示4*4的item信息(本文最后有附图).由于网络数据获取较多且随时需要保持页面内app下载进度及状态,所以出现以下性能问题

Android内存优化1-对Bitmap的内存优化

在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间.那为什么还需

【转】Android开发之Bitmap的内存优化详解

本文来源:转载自: http://mobile.51cto.com/abased-410796.htm 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1.要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系

关于android性能,内存优化

随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要 求远远高于PC的桌面应用程序.以上理由,足以需要开发人员更加专心去实现和优化你的代码了.选择合适的算法和数据结构永远是开发人员最先应该考虑的事 情.同时,我们应该时刻牢记,写出高效代码的两条基本的原则:(1)不要做不必要的事:(2)不要分配不必要的内存. 我从去年开始接触Android开发,以下结合自己的一点项目经验,同时参考了Google的优化文档和网

Android应用开发中对Bitmap的内存优化

在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间.那为什么还需

Android开发优化之——对Bitmap的内存优化

http://blog.csdn.net/arui319/article/details/7953690 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Androi

Android学习之内存优化(一)—— 图片处理

在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap. 对于图片,内存优化中有两个手段,一是减少图片本身所占的内存.二是缓存经常使用的图

android 开发如何做内存优化

网上看的一篇很好的文章;http://www.gforetell.com/?/question/id-111__uid-focus 不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造成了内存泄露.如果我们的java运行很久,而这种内存泄露不断的发生,最后就没内存可用了.当然java的,内存泄漏和C/C++是不一样的.如果java程序完全结束后,它所有