Skip to content

LVGL 内存溢出排障:DRAM 差 88 字节怎么办

ESP32 上跑 LVGL 最容易遇到的编译错误之一:

region `dram0_0_seg' overflowed by 88 bytes

先搞清:你的大对象进了哪里

Arduino 框架下,普通静态数组 / 全局对象默认放在 DRAM。LVGL 的 buffer、字体位图、控件对象一旦变多,DRAM 就爆。

排查顺序建议:

  1. 看编译输出的内存报告,确认是谁占了 DRAM;
  2. 真正的大块(如 LVGL draw buffer)显式放进允许的外部 RAM 段;
  3. 小对象不要乱挪——搬运本身有开销,DRAM 塞得下就不动。

EXT_RAM_BSS_ATTR 的真相

很多人(包括我)以为加上 EXT_RAM_BSS_ATTR 就把变量挪出 DRAM 了,实际并非总是如此:

  • 在部分分区/编译配置下该属性不生效,变量还是落在 DRAM;
  • 更反直觉的是:开启 PSRAM 后,SPIRAM 驱动自身也要吃内存,某些工程净效果是反而多占 100+ 字节;
  • 结论:一切以编译后的实际内存报告为准,不要根据"应该有效"来推断。

让 UI 活下来的几条路

  • 字库按需打包:全字号字体只打包用到的字号,CJK 用单独的回退字体;
  • 把大字体/位图从 flash 挪到 SD 卡 / 文件系统 按需加载(还能顺带解锁 OTA 升级);
  • UI 只建一次控件,复用而非反复 create/delete。

一句话总结

内存排障没有银弹,唯一可靠的办法是读编译报告 + 一次只改一处,改完看内存数字说话。