Files
endorphin-tessera-gui/examples/gc-lifecycle.endor
T

49 lines
2.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 托管对象循环与等待帧回收:先记 ui.stats().objects,再调用 mountCycle,观察 phase 与 pending.value.status()。
// 关闭临时页仍可因业务引用保留等待任务;releaseCycle 清掉外部引用后,缓存不应让整个引用环常驻。
// 比较操作前后对象数时,关闭页面只解除展示根;holder/pending 外部引用也释放后才应回到基线。
holder = ui.state(0)
pending = ui.state(0)
phase = ui.state(0)
// 通过 peer 指回包含自己的 Page,配合等待协程形成包含视觉缓存读依赖的引用环。
class CycleRect: RectBlock {
peer: Object
// sleep 归属该 rect,await 保留协程帧;先写 phase=1,只有实际恢复后才写 2 并改 Page 标题。
function wait(self: CycleRect): Unit {
gate = ui.sleep(self,"sleep",300000)
phase.set(1)
done = await gate
phase.set(2)
self.peer.title = "等待已结束"
}
// 故意读取 peer.title,让布局依赖包含循环中的 Page;缓存应借用观察,不增加长期 GC 根。
function measure(self: CycleRect, mount: Mount, constraints: Constraints): MeasureResult {
observed = self.peer.title
return MeasureResult(180,40)
}
// 绘制也读取 peer.title,检查绘制缓存与等待帧不会共同意外保活循环。
function paint(self: CycleRect, mount: Mount, geometry: Bounds): DisplayList {
observed = self.peer.title
return RectBlock.paint(self,mount,geometry)
}
}
// 创建临时 Page 和 CycleRect,相互引用后挂载,再把 Page/Task 分别放入两个外部 holder。
function mountCycle(): Unit {
transient = Page()
transient.title = "临时引用环"
rect = CycleRect(180,40,8,"#3868D9",transient)
transient.render(rect)
holder.set(transient)
phase.set(0)
pending.set(ui.spawn(rect,"workflow",rect.wait))
}
// 先关闭临时页,随后去掉两个外部引用;等待依赖无需等满五分钟,失去可达性后应整体回收。
function releaseCycle(): Unit {
holder.value.close()
holder.set(0)
pending.set(0)
}
// 基线页面始终存在,用它比较操作前后的托管对象数,不把临时页面当作基线。
base = Page()
base.title = "GC 基线"
base.render(TextBlock("关闭临时 Page 后应回收引用环",2))