对于内存资源有限的Android设备,如1G、2G或3G RAM的项目,合理配置zram(压缩内存交换)是提升系统流畅度的关键。本文旨在深入解析在不同硬件平台上设置zram disksize的实践方法。
平台配置方法
高通平台设置
高通平台的zram配置相对直接,通常通过在启动脚本中判断物理内存总量来设置。
相关代码位于 init.qcom.post_boot.sh 文件中:
if [ -f /sys/block/zram0/disksize ]; then
if [ -f /sys/block/zram0/use_dedup ]; then
echo 1 > /sys/block/zram0/use_dedup
fi
if [ $MemTotal -le 524288 ]; then
echo 402653184 > /sys/block/zram0/disksize
elif [ $MemTotal -le 1048576 ]; then
echo 805306368 > /sys/block/zram0/disksize
else
echo $zRamSizeBytes > /sys/block/zram0/disksize
fi
fi
配置逻辑清晰:根据 $MemTotal 的值(单位KB),直接写入相应的 disksize 字节数。
联发科(MTK)平台设置
以较新的 Kernel-4.9 为例(旧版本内核略有差异),MTK提供了两种设置zram disksize的方式。
方式一:直接设置参数
在 fstab.enableswap 文件中,直接指定zram设备的大小(单位为字节)。
/dev/block/zram0 none swap defaults zramsize=1073741824
方式二:按比例设置
同样在 fstab.enableswap 中,可以使用百分比来定义大小。
/dev/block/zram0 none swap defaults zramsize=50%
重要提示:此处的“比例”并非直接对应物理内存(RAM)的比例。其计算基数是系统启动完成后的 TotalRam(包含了某些预留内存归还后的总值)。因此,对于期望设置“物理内存50%”的需求,直接写50%可能无法达到预期效果。
该比例值的解析在 android/system/core/fs_mgr/fs_mgr_fstab.cpp 文件中:
} else if (StartsWith(flag, "zramsize=")) {
if (!arg.empty() && arg.back() == '%') {
arg.pop_back();
int val;
if (ParseInt(arg, &val, 0, 100)) {
entry->zram_size = CalculateZramSize(val);
} else {
LWARNING << "Warning: zramsize= flag malformed: " << arg;
}
} else {
if (!ParseInt(arg, &entry->zram_size)) {
LWARNING << "Warning: zramsize= flag malformed: " << arg;
}
}
}
深度定制方案
由于项目通常存在不同RAM大小的硬件变种,固定值或平台的比例参数可能不适用。更理想的方案是根据实际的物理内存大小动态设置 disksize。这通常需要深入Linux内核驱动层进行修改。
disksize 的最终设置位置在 kernel-4.9/drivers/block/zram/zram_drv.c 文件的 disksize_store 函数中:
disksize_store() --> set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
我们可以在此函数中进行客制化,根据 totalram_pages(总内存页数)判断并写入目标值。以下是一个示例修改:
disksize = memparse(buf, NULL);
if (!disksize)
return -EINVAL;
/* 根据总内存大小设置zram disksize */
+ if (!totalram_pages)
+ return -EINVAL;
+ if (totalram_pages < 262144) { // 对应 1G RAM (262144 * 4KB)
+ disksize = 536870912; // 设置为 512M
+ } else if (totalram_pages < 524288) { // 对应 2G RAM
+ disksize = 1073741824; // 设置为 1G
+ } else if (totalram_pages < 786432) { // 对应 3G RAM
+ disksize = 1610612736; // 设置为 1.5G
+ }
down_write(&zram->init_lock);
if (init_done(zram)) {
pr_info("Cannot change disksize for initialized device\n");
err = -EBUSY;
goto out_unlock;
}
此方案的思路借鉴了 MTK Kernel-3.18 中的默认计算逻辑。在深入进行此类系统优化时,理解内核的内存管理机制至关重要。原逻辑如下:
if (!disksize) {
/* Give it a default disksize */
disksize = default_disksize_perc_ram * ((totalram_pages << PAGE_SHIFT) / 100);
/* Promote the default disksize if totalram_pages is smaller */
if (totalram_pages < SUPPOSED_TOTALRAM)
disksize += (disksize >> 1);
}
它使用了一个百分比来计算默认大小。而我们的客制化需求是直接关联物理内存容量,因此基于此框架进行条件判断修改是可行的方法。