在嵌入式 Linux 设备开发中,内存永远是最稀缺的资源之一。
本文通过在君正 T23D(DDR 32MB) 实践开发中,内存优化经验,涵盖传感器配置、ISP 缓冲、内核裁剪、SWAP 使用等多个维度,抛开 T23 方案原厂 SDK 相关逻辑,很多优化方案在其他 Linux 设备方案仍然适用。
传感器与码流配置优化
分辨率调整
- 主码流输入 1280×720,子码流压缩至 420×216(最佳能改回 640×360)
- 使用三个 FS(Frame Stream):FS1=640×360,FS2=416×224,虽然内存增加 512K,但保证子码流画质
帧缓冲优化
- 视频 VBs 改成 1(有丢帧风险,需确保 sensor 驱动留有足够大的 VTS)
- encoder 的 bufSize 需要显式设置,否则内部会分配一个 YUV 的内存大小,1080P 建议使用 300K
音频缓冲优化
- 音频输入缓冲从 40 降低至 8
- 音频输出缓冲从 40 改成 18(太低会导致播放音频一卡一卡)
- audio.ko 加载时传入
samplerate=16000,否则内部按 96K 采样率分配缓冲,可节省约 300K
ISP 内存优化
ivdc 参数
ISP 的 ivdc 内存大小计算方法:插值以后的宽度 × ivdc_mem_line × 3 / 2
- 1080P 建议 ivdc_mem_line = 540
- 720P 建议 ivdc_mem_line = 360
isp_memopt 参数
ISP 缓冲压缩算法选项:
isp_memopt=0:720P 预计使用内存 2033Kisp_memopt=1:720P 预计使用内存 1353K
rmem 参数
- 720P:
rmem=5M - 1080P:
rmem=0x740000
内核裁剪
文件系统裁剪
- 去掉 exfat 支持(刚性需求需要补回去)
- 原来一些挂载接管目录的行为改成软链接(
/lib/modules、/data)
内核配置优化
- 裁剪 defconfig(去掉不用的 I2C2、MAC 等)
- 内核 PTY 可以减少到 2
- 检查 sqlite3 是否用到 dnotify,是否可以裁剪
SDK 优化
- 音频算法库砍掉 HS,使用
libaudioProcess.a替代动态打开的libaudioProcess.so(这个需要原厂支持) - 设定 root、kernel 不能升级(OTA 文件缓冲)
- 去掉 /tmp 目录下的日志记录,最大时约 512K
使用 SWAP 交换区
当物理内存不够用时,可以使用 zram 压缩交换区:
# 使用 1.5M swap 压缩缓冲
echo 16777216 > /sys/block/zram0/disksize
mkswap /dev/zram0
swapon /dev/zram0
echo 100 > /proc/sys/vm/swappiness
# 查看缓冲状态
free -m
# 有时 free 显示 swap 没有使用,可以尝试执行
echo 3 > /proc/sys/vm/drop_caches
内存占用实测数据
子码流分辨率与内存占用
以 416×234 分辨率为例(对齐后 416×240):
| 内存区域 | 计算公式 | 大小 |
|---|---|---|
| video | 416×240×3.3 | 322,688 |
| VBMPool1 | 416×240×1.5 | 149,760 |
| personDet | 416×240×4.0 | 399,360 |
| 合计 | 871,808 |
如果改为 640×360:
| 内存区域 | 计算公式 | 大小 |
|---|---|---|
| video | 640×360×3.3 | 613,760 |
| VBMPool1 | 640×360×1.5 | 353,280 |
| personDet | 640×360×4.0 | 942,080 |
| 合计 | 1,909,120 |
从 416×234 改为 640×360,内存增加约 1MB。
双 FS 方案内存
如果使用两个 FS(640×360 编码 + 416×224 AI):
- 总内存 = 613,760 + 322,688 + 353,280 + 399,360 = 1,689,088
- 比单 FS 416×234 多出约 817K
优化效果总结
| 优化项 | 节省内存 | 风险 |
|---|---|---|
| audio.ko 指定 samplerate | ~300K | 无 |
| isp_memopt=1 | ~680K(720P) | 需验证画质 |
| 去掉 exfat | 少量 | FAT/exFAT 不兼容 |
| 去掉 /tmp 日志 | ~512K | 调试不便 |
| 使用静态库替代动态库 | 少量 | 增加固件体积 |
| VBs=1 | 显著 | 丢帧风险 |
| SWAP 压缩 | 间接释放 | 性能下降 |
下一步优化方向
- 针对代码栈内存、堆内存优化(工作量大,转化率不一定高)
- 内存池改为全局 malloc/free 分配(会增加碎片,不建议)
- 内核 PTY 减少到 2
