# 9. AWTK 资源占用

程序的 ROM 和 RAM 资源占用一直都是嵌入式开发关心的问题,ROM 上通常存放代码、常量和应用资源数据,RAM 内存通常存放 Framebuffer、AWTK 框架功能以及应用程序的动态内存。应用相关的资源占用与应用的规模强烈相关,而 Framebuffer 则与平台的缓冲数量、屏幕分辨率以及颜色深度等相关,用户可以自行估算出来。本章仅讨论 AWTK 框架功能的资源占用(AWTK 核心和非核心模块代码 ROM 以及 RAM 的占用情况)。

图9.1 资源占用概述图
图9.1 资源占用概述图

# 9.1 资源占用

AWTK 中有核心代码和非核心代码,核心代码就是不能裁剪,必须要添加到项目中的代码,而非核心代码又分为控件和可裁剪的功能模块,所以 AWTK 资源占用可以简单分为三部分:无法裁剪的核心功能模块,可裁剪的功能模块以及控件。本章节讨论是这三部分的资源占用情况。

测试说明:

  1. 本章节的内存占用测试是在 32 位的 MCU 上进行的,在 64 位的 MCU 上测试结果可能会不一样。
  2. 本章节的 ROM 占用测试是在无调试信息以及编译选项为 -Os 的情况下进行的,数据通过 arm-none-eabi-size.exe 测试得到。

# 9.1.1 核心功能模块的资源占用

将 AWTK 的非核心代码全部裁剪掉,核心代码的 ROM 占用约为 100KB,RAM 占用约为 3KB,AWTK 核心模块介绍及其内存占用请参考本文附录三。

需要注意的是:

  1. 由于 AWTK 存在图片缓冲机制,显示全新图片时,如果内存足够,图片管理器的内存都会增加。
  2. 不同的 lcd_t 类型内存占用都不一样,lcd_t 对象一般仅占几百个字节,真正占用内存的是 Framebuffer。
  3. 要注册 UI 控件还需要加上额外的 3KB 控件管理器内存。

在内存资源紧缺的平台上,用户可以在适当时机(比如切换窗口时),手动调用 image_manager_unload_unused 或者 image_manager_unload_all 函数来及时清除图片缓存,避免图片缓冲机制与其他业务逻辑抢资源。

# 9.1.2 可裁剪的功能模块的资源占用

功能模块 ROM 占用 RAM 占用
图片解码模块 WITH_STB_IMAGE 约 35.9KB PNG:解码瞬时峰值内存占用约为两份位图数据。
JPG:18KB + 解码瞬时峰值内存占用约为三份位图数据。
GIF:解码后大约为所有帧的位图数据总和
字体解码模块 WITH_STB_FONT 约 15.1KB stb 字库对象为:3.2KB + 用到的字模缓存数据
标准的 UNICODE 换行算法模块 WITH_UNICODE_BREAK 约 47.3KB 大于1.39KB
Google 拼音输入法功能 WITHOUT_INPUT_METHOD、 WITH_NULL_IM 约 24.5KB + 1.1MB(输入法资源) 大于700KB
AGGE 矢量画布模块 WITH_NANOVG_AGGE 约 10KB 大于 30KB(18.8KB + 缓存数据)
窗口动画功能 WITHOUT_WINDOW_ANIMATORS 约 3.3KB 520B + 两份显存大小的瞬时峰值
布局算法模块 WITHOUT_LAYOUT 大约 1.9KB 128B
控件动画功能 WITHOUT_WIDGET_ANIMATORS 大约 3KB 120B
剪切板模块 WITHOUT_CLIPBOARD 大约 232B 16B
对话框高亮策略模块 WITHOUT_DIALOG_HIGHLIGHTER 大约 1.2KB 60B
加载文件系统资源模块 WITH_FS_RES 大约 5.5KB 0B
扩展控件 WITHOUT_EXT_WIDGETS 大约 90KB 0B
基本控件 AWTK_NOGUI 大约 12.3KB 0B

需要注意的是:

  1. WITH_ 开头的宏用于开启某个功能模块,WITHOUT_ 开头的宏用于裁剪某个功能模块,通常 AWTK 默认开启的功能,需要用 WITHOUT_ 开头的宏来裁剪,默认不开启的功能,需要用 WITH_ 开头的宏来开启。
  2. 图片解码器最大的问题是解码时,峰值内存较高,尤其是在解码 JPG 时,如果 JPG 类型为 YUV ,峰值会根据 YUV 的采样比来决定,上表中默认采样比为 1,如果采样比大于 1,峰值内存只会更大。
  3. JPG 和 PNG 解码完成后,会释放解码时开辟的多余的峰值内存,将一份解码后的位图的数据存放到 AWTK 的图片缓冲中。
  4. GIF 格式的解码仅在开启图片解码模块以及通用文件系统模块时支持,并且解码后的 GIF 所有帧都会被拼接到一张 bitmap 中,所以 GIF 的内存占用为所有帧的位图数据总和。
  5. Truetype 字体解码器本身不占什么内存,但由于缓存机制,字模的内存占用会随着显示字符的增多而变大,每个字模内存约等于字号*字号所占字节。
  6. Nanovg 和 Agge 是 AWTK 自带的第三方的矢量画布类库。
  7. 在矢量画布中,缓存数据分别在 nanovg 和 AGGE 中,nanovg 创建的时候默认包含了 128 个 point(约 32B),16 个 path(约 40B)和 256 个 vertex(约 16B),但如果运行过程中同一帧内的缓存数据超过默认的缓存数量,就会重新分配缓冲数据,这会增加矢量画布的内存占用量。
  8. AGGE 创建时没有默认缓存数据,它绘制前会把 nanovg 的缓存数据转为坐标点(约 12B),如果当前的坐标点个数超过之前缓存的坐标点个数,就会重新分配缓存坐标点数组,同时如果让 AGGE 画一个全新的图片,就会增加一个贴图缓存(约 32B),所以 AGGE 运行时会增加矢量画布的内存占用量。

# 9.1.3 控件的资源占用

关于控件的资源占用:

  1. 除了控件自身的最低运行内存占用以外,修改控件相关属性以及设置 inline_style(在 UI 文件中增加的风格属性就是 inline_style),都可能导致控件的内存变大,同时每创建一个控件就会多占用一份内存,每个控件的内存都是独立的。

  2. 控件占用的 ROM 计算比较简单,每种控件的 ROM 占用都是固定的,而且还有一些控件是公用同一个代码文件的,所以多个控件占用同一份 ROM。

下面列出一些常用的控件资源占用列表,在附录四中会列出所有 AWTK 的控件资源占用列表。

控件名称 ROM 占用 最少 RAM 占用
dialog 大约 1.2KB 424B
window 567B 412B
image 大约 1KB 168B
button 大约 1.7B 160B
label 大约 3.3KB 148B
progress_bar 大约 2.5KB 160B
check_button 大约 1.6KB 140B
radio_button 大约 1.6KB 140B
system_bar 983B 444B
system_bar_bottom 983B 444B
view 509B 140B
edit 大约 19.5KB 868B
combo_box 大约 5.5KB 大约 1.2KB
combo_box_item 大约 1.3KB 144B
scroll_view 大约 6.6KB 272B
list_view 大约 3KB 160B
list_item 大约 1KB 152B
scroll_bar 大约 5.8KB 164B
scroll_bar_d 大约 5.8KB 920B
scroll_bar_m 大约 5.8KB 164B
combo_box_ex 601B 大约 1.4KB

# 9.2 评估项目资源占用方法

# 9.2.1 评估项目 AWTK 相关 ROM 的大小

只保留 AWTK 的核心代码和基础控件时 ROM 约为 130KB,根据实际需求再加上使用的控件和功能模块的 ROM 大小。如果没有定义 WITHOUT_EXT_WIDGETSAWTK_NOGUI 宏,那么控件占用的 ROM 分别为 90KB 和 12.3KB,不论用到多少个控件,都占用相同的 ROM。

# 9.2.2 评估项目 AWTK 相关 RAM 内存大小

假设 LCD 是 800 * 480 的 16 位色屏幕,采用双 Framebuffer 机制,计算内存的步骤如下:

  1. 双 Framebuffer 的显存为:800 * 480 * 2 * 2 = 1.5MB。

  2. 估算 AWTK 使用的总 Heap 大小:

    (1) 计算 Heap 中的小对象内存池大小,详见附录三。

    (2) 统计要使用的可裁剪的功能模块,计算所用到的模块的内存总和。

    (3) 统计要使用的控件,以及同一画面中有多少个控件,计算所有显示的控件的内存占用总和。

    (4) 如果开启了图片解码模块,则需要计算解码峰值,以及同一个画面显示的所有贴图缓存的内存总和。

    (5) 如果开启了字库解码模块,则需要计算同一个画面显示的所有字符缓存的内存总和。

    (6) 如果开启窗口动画模块,则需要分配额外两份 Framebuffer 大小的内存,用于保存前后两个窗口的截图。

    (7) 程序运行过程中可能会出现内存碎片,汇总好以上内存占用量之后,再乘以系数 1.2 到 2,就可以得出来项目大概需要多少内存。

# 9.2.3 评估项目其他资源占用

不同领域的项目应用程序规模差异较大,用户需要自行估算其他业务逻辑的 ROM 和 RAM 占用,以及用到的图片字体等资源数据的 ROM 占用情况。

在项目资源中,通常占 ROM 最多的通常是图片资源和字体资源,其中字体资源可以通过 AWTK Designer (opens new window) 的资源管理器进行裁剪。

# 9.3 平台资源和功能模块裁剪建议

# 9.3.1 ROM 和功能模块

该表中仅代表 AWTK 本身占用的 ROM,不包括应用程序自己的的代码以及资源数据。

平台 ROM 大小 建议裁剪(禁用)的 AWTK 功能
高资源平台 (2MB, +∞ ]
中资源平台 (256KB,2MB] 拼音输入法功能(包括输入法资源,约占 1.1MB ROM)
低资源平台 (128KB,256KB] 除位图字体功能,位图贴图功能以及部分基本控件之外的所有功能

# 9.3.2 内存和功能模块

该表中仅代表 AWTK 本身占用的运行内存,不包括显存和应用程序所需的其他业务内存。内存比较小的情况下尽量使用相同字号和相同字库的字符。

平台 RAM 大小 建议裁剪(禁用)的 AWTK 功能
高资源平台 (4MB, +∞ ]
中资源平台 (2MB,4MB] 拼音输入法功能(包括输入法资源)
中资源平台 (1MB,2MB] 播放窗口动画模块,对话框高亮策略模块,图片解码功能
低资源平台 (512KB,1MB] 布局算法模块,Truetype 字库解码模块, AGGE 矢量画布模块
低资源平台 (128KB,512KB] 标准的 UNICODE 换行算法, 剪切板算法,加载文件系统资源模块
低资源平台 (10KB,128KB] 除位图字体功能,位图贴图功能以及部分基本控件之外的所有功能