微信号:androidperf

介绍:分享android 性能优化/android power 优化技术,经验.

Android 性能优化—Android memory 参数tuning(二)

2016-01-11 21:31 androidperf

ART

我们知道ARTAndroidKK中引入,L 中正式发布.L 及以后的版本中androidruntime就是只有ART.然而ART 依然沿用Dalvik中的参数.为了更好理解ART参数的含义我们来看看ARTJavamemory分配情况.

Image space

Zygote Space

Non Moving Space

Main ROS alloc space

bump pointer space/temp space

large object

Boot.art

Boot.oat

Image Space:这部分包含boot.artboot.oat两部分.boot.oat是一个OAT文件,它是dex2oat工具把系统启动类路径中的所有DEX (byte code) 文件编译为本地native文件 (ELF).为了提高ART运行的性能, ART会对一些常用, 基础的系统classes做初始化并create 相关的对象并生成image 这就是boot.art.以后只要系统启动类路径中的DEX文件不发生变化(即不发生更新升级),那么以后每次系统启动只需要将文件system@framework@boot.art直接映射到内存即可,省去了创建各个类对象的时间。因此,虽然ART运行时第一次启动时会比较慢,但是以后启动实际上会更快。

Zygote Space: preload class/resource/objects forzygote 并且这些资源在Zygote进程和应用程序进程之间共享.

Non Moving Space:不可移动space, 比如Class/ArtMethod/ArtField.

Main Space: Java中创建的小的object(小于12k).

Large Object Space: Java 中创建的大的object (大于12K ,3*pagesize),这个一个单独的分区

其中,前四个memory需要连续的物理内存.LargeObject Space 不需要连续的物理内存.

bump pointer space/temp space: 这部分空间用于SS ,CM 类型的GC .

ART 对系统或者UX的主要贡献在GC.也就是说如果GC发生, 那么系统的性能和UX就会变差.例如如果我们正在玩游戏,high的时候, GC来了.那么所有的javaspace 程序可能就会pause,进而造成掉帧.当然并不是说有的GC都会引起这个问题例如并行GC便不会. 那么GC 是可遇而不可求的.一般来说在如下两种情况下会发生GC.

  • Allocation failed 从而 trigger GC.由于分配memory失败而引发GC,如果这种GC发生往往会影响系统的性能.

  • Low memory 引发的GC.这种GC的严重程度轻于前者.它只能GCdaemon发起, 其发生的条件是当Allocation成功后, check 分配的size是否超过了并发GC的条件如是, triggerGC.


ART中主要参数如下,

  • dalvik.vm.heapstartsize

    ART 初始化Java 堆的大小.这是一块连续的物理内存.如果这个参数设得太小, app启动是会频繁的分配object所要求的内存.这样会影响app的启动速度.如果这个参数太大会浪费内存.如果想tuning这个参数,需要进行大量的测试.

  • dalvik.vm.heapgrowthlimit

    这个参数是常规Java app能分配的最大的java heap,包含NonMoving Space, Main SpaceLargeObject Space.也就是说一个App的所有java 对象所用的memroy不能超过这个参数的值.

  • dalvik.vm.heapsize

    其含义与dalvik.vm.heapgrowthlimit相同.但是这个参数是对largeHeap-enabled 应用起作用.也就是说如果largeHeap-enabled那么一个appjava 内存不能超过此参数的值.否则则不能超过dalvik.vm.heapgrowthlimit参数的值.android3.0开始,appjava heap的需求分为两类,一是通常的app,另一类是largeHeap-enabled.如果我们的app需要大的javaheap我们需要在AndroidManifest.xml文件中添加如下的代码.

    <application

    android:largeHeap="true"

    </application>

  • dalvik.vm.heaptargetutilization/dalvik.vm.heapminfree/dalvik.vm.heapmaxfree

它们用来确保每次GC之后,Java堆已经使用和空闲的内存有一个合适的比例,这样可以尽量地减少GC的次数。举个例子说,堆的利用率为U,最小空闲值为MinFree字节,最大空闲值为MaxFree字节。假设在某一次GC之后,存活对象占用内存的大小为LiveSize。那么这时候堆的理想大小应该为(LiveSize/ U)。但是(LiveSize/ U) 必须大于等于(LiveSize+ MinFree)并且小于等于(LiveSize+ MaxFree)。它们相互作用来对GCjavaheap堆的控制.


参考值:

dalvik.vm.heapstartsize16M

dalvik.vm.heapgrowthlimit192M

dalvik.vm.heapsize 512M

dalvik.vm.heapminfree 6M

dalvik.vm.heapmaxfree 14M

dalvik.vm.targetutilization 0.75

LMK

我们知道Android尽可能keep较多的后台应用程序.这样当用户启动后台程序时,由于其在memory, 启动就会很快完成,给用户比较好的用户体验.但是另一方面,如果keep的应用程序足够多,系统的memory就会吃紧,系统就会越来越慢.LMK就应允而生.LMK(lowmemory killer)在两种情况下可能发生,一种是在分配memory,如果系统没有足够的可用内存,那么LMK 就会trigger.Kill掉屌丝app(占用了大量的memory,优先级又比较低);另一种情况是系统的内存不够时,kswapd便会free 内存,那么LMK也会被trigger,屌丝app也会被kill.

Android按照app运行状态和app的属性把app分为几类并给每一个app设置 adj.Adj值越大的app说明其优先级越低.在系统内存不够时,LMK会首先killadj值最大并且占用memory最多的app.Appadj会根据其运行状态和系统的状态动态的改变.一般来说LMK把可被killappadj值分为6level, 每一个leveladj都有一个对应的minfreememory值想对应.当系统freememory值低于minfree, LMK 便kill掉其相应的adj值中占用memory最大的app.

我们可以用下面的命令来获得LMK的值.

adb shell cat /sys/module/lowmemorykiller/parameters/adj

adb shell cat /sys/module/lowmemorykiller/parameters/minfree

:

adb shell cat /sys/module/lowmemorykiller/parameters/adj

0,58,117,176,529,1000

adb shell cat /sys/module/lowmemorykiller/parameters/minfree

18432,23040,27648,32256,55296,80640

则其kill的规则如下,

这里的adj0,58,117,176,529,1000,其对应的minfree18432,23040,27648,32256,55296,80640.也就是adj值为1000app其对应的系统内存最小值80640x4k,adj值为529app其对应的系统内存最小值为55296x4k,adj值为0app其对应的系统内存最小值18432x4k. Adj值越小其优先级越高,所以其minfree值也越小,其也就越不容易被LMK kill. 当系统的cachememoryfreememory都小于某些值时,LMK便会选择相关的appkill. 例如如果系统的cachememory freememory在某一时刻都小于300M<80640x4k,那么LMK便会在adj大于等于1000的所有app中挑选其占用memory最大的appkill.

综上所述,我们可以给adj设置合适值minfree来做到memory和系统性能平衡.系统会根据devcieLCD resolution,memory大小给出一组初始值.但是我们应该根据系统安装应用的情况,应用的性质,应用使用memory的大小来tuning这些参数.如果阈值设置过低,可用的memory就会较少,可能会引起OOM错误,如果阈值设的太高,内存就会得不到充分的利用而且LMK会很频繁反而影响系统的性能浪费了memory.


 
Android性能优化 更多文章 Android Performance Case Study Android Performance Case Study(二) Android Graphic 架构 骁龙820 号称最强机 Android App Launching Made Gorgeous
猜您喜欢 【Container讲师专访】容器化技术在长安汽车中的实践 百度停止社招之后,第一个破例名额竟然是他 POW:Knock Out Rails & Rack Apps “微软热爱Linux“ – 心声传遍中国 html样式表css3-盒子模型