android支持设备使用512M低内存。有以下优化点在系统中使用
在开发应用中增加一些开发选项,显示应用内存状态和统计应用内存使用频率和内存消耗程度。
API
应用中使用ActivityManager.isLowRamDevice(),确保在运行时检测到地内存和关闭占用大量内存的特性。
内存使用跟踪
使用dumpsys meminfo,分类归总内存信息。其中free memory包含缓存进程占用的内存。
配置
PRODUCT_PROPERTY_OVERRIDES += ro.config.low_ram=true
确保ActivityManager.isLowRamDevice()返回为true
请务必确保启动器的默认壁纸设置未使用动态壁纸。低内存设备不应预装任何动态壁纸。
当kernel使用了所有可用内存,一个进程或者kernel申请一个内存页时,会触发内存回收再利用。这时,内存申请被阻塞,直到释放足够内存。内存回收再利用会把缓存的内存信息写在存储器(如emmc)中或者触发lowmemorykiller杀掉一些进程。这样做的结果是阻塞I/O和UI线程。前台
为了避免直接出发内存回收再利用,内核可配置为触发kswapd或者后台内存回收再利用,确保下次申请内存时有足够的内存分配。
默认的后台内存回收再利用阈值很低,在2G的设备上阈值时2M,512内存设备上阈值是636KB,内存也仅仅可以回收很少的内存。意味着任何进程申请内存的速度快于内存回收的速度,都会触发前台内存回收再利用。
为了支持可配置,在android-3.4分支,patch 92189d47f66c67e5fd92eafaa287e153197a454f (增加额外内存回收配置)。合入该patch,默认ActivityManager 可以告知内核试着拥有3 full-screen 32 bpp buffers的内存。
// Ask the kernel to try to keep enough memory free to allocate 3 full
// screen 32bpp buffers without entering direct reclaim.
int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
...
SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
该阈值在framework的config.xml中配置
-1
0
生效方式
$ grep -nr "sys.sysctl.extra_free_kbytes"
frameworks/base/services/core/java/com/android/server/am/ProcessList.java:297: SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
system/core/rootdir/init.rc:664:on property:sys.sysctl.extra_free_kbytes=*
system/core/rootdir/init.rc:665: write /proc/sys/vm/extra_free_kbytes ${sys.sysctl.extra_free_kbytes}
配置LowMemoryKiller 的阈值根据内存使用情况可变,当内存多次处于不足时,会增加内核中预准备内存值。当内存需求量不大时,会降低该阀值。
-1
0
zRAM通过压缩内存页,然后放置在动态申请的交换内存区,增加内存的可用量。
由于zRAM会导致内存中交换,增加cpu占用,谨慎评估使用zRAM对系统性能的影响。系统处理swap to zRAM 有以下几个级别:
/dev/block/zram0 none swap defaults zramsize=,swapprio=
为交换区设置selinux权限
/dev/block/zram0 u:object_r:swap_block_device:s0
write /proc/sys/vm/page-cluster 0
swapon_all /fstab.X
在低内存设备,碎片内存需要关注,尤其哪些不能被充分利用。比如一个视频回放内存分配。有多种解决方案把硬件需求的区域影响降低到最低(不太明白什么影响)
如果hardware准许使用非连续内存申请,ion system heap 可以申请内存在系统内存,排除内存分割。如果需要分配一段连续或者被配置特定地址的区域,使用CMA申请内存。CMA通过ion,直接简单的使用ion cma heap。
http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html
http://android-developers.blogspot.com/2009/02/track-memory-allocations.html
http://tools.android.com/recent/lintperformancechecks
使用adb shell am start,加上-P或者–start-profiler选项,启动app的同时启动分析器。该命令在虚拟机fork app 进程后立即启动分析器,在任何代码加载之前。
如batterystats, netstats, procstats, and usagestats等
重启系统,记录进程状态
运行几个小时后,再次记录进程状态,对比数据分析,此时不应该有长时间运行的进程
长时间运行设备测试,监控内存变化。创建不同场景,压力测试分析变化