低内存配置

2018-08-28  本文已影响0人  ben3726

原文:https://source.android.com/devices/tech/perf/low-ram

介绍

Android现在支持512MB RAM的设备。本文旨在帮助OEM为低内存设备优化和配置Android 4.4。其中一些优化非常通用,它们也可以应用于以前的版本。

Android 4.4平台优化

改进了内存管理

减少系统内存

进程统计

添加新的开发者选项,用于显示内存状态和应用程序内存使用情况,并根据运行频率和内存消耗量进行排序。

API

添加新的ActivityManager.isLowRamDevice(),用于允许应用程序检测何时在低内存设备上运行并选择禁用大RAM功能。

内存跟踪

新memtrack HAL用于跟踪图形内存分配,dumpsys meminfo中的附加信息,meminfo中的概要说明(例如报告的可用RAM包括缓存进程的RAM,以便OEM不会尝试优化错误的东西)。

构建时配置

启用低Ram设备标志

我们正在引入一个名为ActivityManager.isLowRamDevice()的新API ,以便应用程序确定是否应该关闭在低内存设备上运行不佳的特定内存密集型功能。

对于512MB设备,此API有望返回true。它可以通过设备makefile中的以下系统属性启用。

PRODUCT_PROPERTY_OVERRIDES + = ro.config.low_ram = true

Launcher配置

确保Launcher上的默认壁纸设置 使用动态壁纸。低内存设备不应预安装任何动态壁纸。

内核配置

调整内核/ActivityManager以减少直接回收

当进程或内核尝试分配一页内存(直接或由于新页面中的错误)并且内核已使用所有可用空闲内存时,会发生直接回收。这要求内核在释放页面时阻止分配。相反,这经常需要磁盘I/O清除垃圾文件(备份页面)或等待lowmemorykiller终止进程。这可能导致任何线程中的额外I/O,包括UI线程。

为避免直接回收,内核具有触发kswapd或后台回收的水印。这是一个试图释放页面的线程,因此下一次真正的线程分配它可以快速成功。

触发后台回收的默认阈值相当低,2GB设备上约为2MB,512MB设备上为636KB。并且内核回收在后台只回收了几MB的内存。这意味着快速分配超过几兆字节的任何进程都将很快导致直接回收。

android-3.4内核分支中添加了对新内核可调参数的支持,见补丁92189d47f66c67e5fd92eafaa287e153197a454f(“添加额外的空闲kbytes可调”)。将此补丁合入到设备的内核将允许ActivityManager告诉内核尝试保留3个全屏32 bpp内存缓冲区。

可以通过框架config.xml配置这些阈值

<!-- Device configuration setting the /proc/sys/vm/extra_free_kbytes tunable
in the kernel (if it exists).  A high value will increase the amount of memory
that the kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier.  A low value allows more memory to be used by
processes but may cause more allocations to block waiting on disk I/O or
lowmemorykiller.  Overrides the default value chosen by ActivityManager based
on screen size.  0 prevents keeping any extra memory over what the kernel keeps
by default.  -1 keeps the default. -->
<integer name="config_extraFreeKbytesAbsolute">-1</integer>

<!-- Device configuration adjusting the /proc/sys/vm/extra_free_kbytes
tunable in the kernel (if it exists).  0 uses the default value chosen by
ActivityManager.  A positive value  will increase the amount of memory that the
kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier.  A negative value allows more memory to be
used by processes but may cause more allocations to block waiting on disk I/O
or lowmemorykiller.  Directly added to the default value chosen by
ActivityManager based on screen size. -->
<integer name="config_extraFreeKbytesAdjust">0</integer>

调整LowMemoryKiller

ActivityManager配置LowMemoryKiller的阈值,以匹配在每个优先级存储桶中运行进程所需的文件(支持页面(缓存页面))的工作集的期望。如果设备对工作集具有高要求,例如,如果厂商UI需要更多内存或者如果添加了更多服务,则可以增加阈值。

如果为文件支持的页面保留了太多内存,则可以减少阈值,因此在因缓存变得太小而导致磁盘抖动发生之前后台进程将会被长时间终止。

<!-- Device configuration setting the minfree tunable in the lowmemorykiller
in the kernel.  A high value will cause the lowmemorykiller to fire earlier,
keeping more memory in the file cache and preventing I/O thrashing, but
allowing fewer processes to stay in memory.  A low value will keep more
processes in memory but may cause thrashing if set too low.  Overrides the
default value chosen by ActivityManager based on screen size and total memory
for the largest lowmemorykiller bucket, and scaled proportionally to the
smaller buckets.  -1 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAbsolute">-1</integer>
<!-- Device configuration adjusting the minfree tunable in the
lowmemorykiller in the kernel.  A high value will cause the lowmemorykiller to
fire earlier, keeping more memory in the file cache and preventing I/O
thrashing, but allowing fewer processes to stay in memory.  A low value will
keep more processes in memory but may cause thrashing if set too low.  Directly
added to the default value chosen by          ActivityManager based on screen
size and total memory for the largest lowmemorykiller bucket, and scaled
proportionally to the smaller buckets. 0 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAdjust">0</integer>

交换到zRAM

zRAM交换可以通过压缩内存页面并将它们放入动态分配的内存交换区域来增加系统中可用的内存量。

同样,由于内存的小幅增加会占用CPU时间,因此您应该仔细测量zRAM交换对系统的性能影响。

Android在几个级别处理交换到zRAM:

/dev/block/zram0 none swap defaults zramsize=<size in bytes>,swapprio=<swap partition priority>
*   `zramsize`是必需的,表示您希望zram区域保留多少未压缩的内存。通常观察到30-50%范围内的压缩比。
*   `swapprio` 是可选的,如果没有多个交换区域则不需要。

您还应确保在设备特定的[ sepolicy/file_contexts](https://source.android.com/security/selinux/implement.html)中将关联的块设备标记为swap_block_device,以便SELinux正确处理它。
/dev/block/zram0 u:object_r:swap_block_device:s0
write /proc/sys/vm/page-cluster 0
swapon_all /fstab.X

Carveouts,Ion和连续内存分配(CMA)

特别重要的是在低内存设备上要注意清理,特别是那些并不总是被充分利用的设备 - 例如用于安全视频播放的分区。有几种解决方案可以根据硬件的具体要求,最大限度地减少削减区域的影响。

如果硬件允许不连续的内存分配,离子系统堆允许从系统内存分配内存,从而无需进行分割。它还试图进行大量分配以消除外围设备上的TLB压力。如果存储区必须是连续的或局限于特定的地址范围,则可以使用连续的存储器分配器(CMA)。

这创建了一个系统也可以用于可移动页面的分割。当需要该区域时,可移动页面将从中移出,允许系统在空闲时将大型分区用于其他目的。使用离子cma堆,CMA可以直接使用或更简单地通过离子使用。

应用优化提示

<data android:scheme="package" android:ssp="com.android.pkg1" />
<data android:scheme="package" android:ssp="com.myapp.act1" />

了解Android中的各种流程状态

分析

分析应用启动时间

在应用启动时,使用$ adb shell am start 命令加上 -P--start-profiler选项运行探查器。在您的任何代码加载到zygote之前,这将在您的进程从zygote创建后立即启动探查器。

使用bugreports进行分析

包含当前可用于调试的各种信息。这些服务包括batterystatsnetstatsprocstats,和usagestats。您可以使用以下行找到它们:

------ CHECKIN BATTERYSTATS (dumpsys batterystats --checkin) ------
7,0,h,-2558644,97,1946288161,3,2,0,340,4183
7,0,h,-2553041,97,1946288161,3,2,0,340,4183

检查任何持久进程

重新启动设备并检查进程。
运行几个小时,然后再次检查进程。不应该有任何长时间运行的进程。

进行长寿测试

运行更长的持续时间并跟踪进程的内存。它增加了吗?它保持不变吗?创建Canonical用例并在这些场景下运行长寿测试。

上一篇 下一篇

猜你喜欢

热点阅读