Fixed Application Arena / 固定 App 内存区

PixelUI 不用 new/delete 创建 App。ViewManager 内部的 ApplicationStack 保留一块固定字节区,所有活着的 App 按页面栈顺序原地构造在里面。

ApplicationStack arena layout

App A 和 App B 只占用各自实际需要的字节,中间的 pad 由对齐要求决定。对象字节与 metadata 分开:metadata 记录回滚位置和具体析构函数,不需要从 arena 字节反推对象边界。

Arena 字节数、最大对齐和页面深度都是固定配置,集中列在资源上限

布局

1
2
3
4
5
arena begin
| App A | padding | App B | free space ... |
^ marker A ^ marker B ^ current offset

separate metadata: [pointer, marker, end offset, destroy thunk] x depth

每次 push 先按 alignof(T) 对齐当前 offset,检查对齐填充加对象字节是否超过 arena,然后 placement-construct。只有构造成功后才提交 metadata。pop 通过具体类型的 destroy thunk 调用正确析构函数,并恢复上一个 marker。

为什么用 LIFO arena

  • 容量和失败可预测;
  • 没有 App 对象的堆碎片;
  • 小 App 只使用自己需要的字节,不用每个槽都按最大 App 预留;
  • 和页面栈一样是 LIFO,回收不需要通用 allocator。

代价是只能销毁栈顶 App,不支持从中间抽掉一页。存活 App 的总大小加对齐填充必须不超过 arena。

Factory 与自定义构造

launch() 使用 AppItem 中的 factory 在 arena 内构造具体类型。常规注册见启动 AppLauncher;特殊构造参数可以使用无捕获 thunk:

1
2
3
4
5
6
AppItem item = AppItem::make<MyApp>(
"My App",
iconBits,
[](void* storage, PixelUI& ui, void*) -> IApplication* {
return ::new (storage) MyApp(ui, fixedItems, fixedItemCount);
});

thunk 只能在 storage 中构造一个声明的具体类型,或者在什么都没构造时返回 null。

实测和目标平台

Apple arm64 Debug 对 v0.3.1-beta 的一次测量为:ApplicationStack=4416ViewManager=4608PixelUI=9216 字节;其中 arena 本身是 4096 字节。这不是对 MCU ABI 的保证,请在实际编译器上重新测量。

1
./build/tests/memory_metrics
最新文章
网站信息
文章数目 :
1
本站访客数 :
本站总浏览量 :
最后更新时间 :