移动端性能专项测试之内存 - 进阶篇

本贴最后更新于 1418 天前,其中的信息可能已经时异事殊

背景

在上两篇文章【移动端性能专项测试之内存泄漏-原理篇】http://testingpai.com/article/1612250666032【移动端性能专项测试之内存泄漏-实战篇】http://testingpai.com/article/1596527701430给大家介绍了内存泄漏相关的知识,在Android系统中内存作为重要的资源,一直是开发及测试关注的重点,内存不足或者内存资源滥用都会导致严重的问题。本篇文章将会从底层出发给大家介绍OOM(Out Of Memory)和LMK(Low Memory Killer)等内存相关的知识。

在Android系统架构中,进程可以大体分成两类,一类是Native进程,另外一类就是Java进程

采用C/C++实现,本质上是linux进程,在/system/bin/目录下面的程序文件运行后都是以native进程形式存在的。

Android虚拟机(Dalvik或者ART)实例的linux进程,进程的入口main函数为java函数。Android虚拟机实例的宿主进程是fork()系统调用创建的linux进程,所以每一个android上的java进程实际上就是一个linux进程,只是进程中多了一个Android虚拟机实例。因此,java进程的内存分配比native进程复杂,Android系统中的应用程序基本都是java进程,如桌面、电话、联系人、状态栏等等。

Android内存限制

Android系统为每一个App设置了可使用的Heap(堆内存)大小限制,可以进入到shell环境中,找到build.prop文件

cat /system/build.prop

dalvik.vm.heapstartsize=8m
app启动后, 系统分配给它的Heap初始大小. 随着App使用可增加
dalvik.vm.heapgrowthlimit=192m
默认情况下, App可使用的Heap的最大值, 超过这个值就会产生OOM
dalvik.vm.heapsize=512m
如果App的manifest文件中配置了largeHeap属性, 如下.则App可使用的Heap的最大值为此项设定值
dalvik.vm.heaptargetutilization=0.75
当前理想的堆内存利用率. GC后, Dalvik的Heap内存会进行相应的调整, 调整到当前存活的对象的大小和 / Heap大小 接近这个选项的值, 即这里的0.75. 注意, 这只是一个参考值.
dalvik.vm.heapminfree=2m
单次Heap内存调整的最小值
dalvik.vm.heapmaxfree=8m
单次Heap内存调整的最大值

LMK(Low Memory Killer)

在用户空间中指定了一组内存临界值,当其中的某个值与进程描述中的oom_adj值在同一范围时,该进程将被Kill掉。如果你的APP某个进程需要一直保存存活,你需要保持你的进程优先级足够高,并且占用比较小,因为Low Memory Killer在工作时,同一优先级的进程会先kill那个占用最大的。性能测试时主要关注待机时的内存是不是够小。

Low Memory Killer的工作可能致系统变卡。为什么呢?因为它kill了一些进程,然而现在市面的很多APP为了保活都会自启,刚刚被kill,立刻又起来。启动占用大量内存(还有CPU),又触发Low Memory Killer。频繁的被kill和启动形成了恶性循环,so…系统变的很卡。

OOM与LMK关系

Google为什么设定当Java进程申请的Java空间超过阈值时,就抛出OOM异常?

如果RAM真的不足,会发生什么呢?

ps:可以通过adb shell cat /proc/meminfo查看RAM的使用情况。

绕过dalvikvm heapsize的限制

对于一些大型的应用程序(比如游戏),内存使用会比较多,很容易超出虚拟机heapsize的限制,这时怎么保证程序不会因为OOM而崩溃呢?

回帖
请输入回帖内容 ...