Memory zh CN - D0n9X1n/SonicTerm GitHub Wiki
下表说明每项内存上限及达到上限后的处理。排查进程增长时,按日志比较连续 采样。本页解释各读数统计什么;协议和图集细节见终端 IO 与 VT 与渲染与字体。
| 所有者 | 精确上限 | 达到上限时 |
|---|---|---|
| 网格几何 | 任一轴 ≤ 4,096;单个可见屏幕 ≤ 524,288 个单元格;可见区 + 历史 + 已保存主屏幕 ≤ 1,048,576 个单元格 | 限制尺寸和请求的历史行数 |
| 网格保留存储 |
MAX_GRID_CELLS × size_of::<Cell>(),当前构建约 24 MiB,由可见区/历史/已保存主屏幕共用;历史行按实际存储的单元格计费,而非按宽度 |
压缩行容量,再以每批 64 行删除最老历史;滚动路径每 512 行摊销检查一次 |
| 单元格组合附加内容 | 每个单元格 64 个 UTF-8 字节 | 不再保留额外零宽数据 |
| OSC 8 注册表 | 16,384 个链接;每个 URI 8 KiB;每个客户端 id 1 KiB;共享字符串与表合计 8 MiB | 回收已无保留单元格引用的条目后接纳;仍无空间则拒绝新链接 |
| 转义序列 | 1 MiB | 一直丢弃到终止符 |
| OSC 0/2/7/8 原始收集器 | 整个负载 16 KiB | 拒绝超长输入;报告保留容量,不增加媒体捕获计数 |
| 媒体负载 | 每个传输 16 MiB | 拒绝,不截断也不局部显示 |
| 媒体捕获暂存 | 进程共 64 MiB;下限 4 MiB;保证 13 个并发下限预留 | 无法暂存时拒绝;连续两次 30 s 采样无进度后取消 |
| 已解码内联图像 | 每窗格 64 MiB 且最多 128 张;256 MiB 进程目标按存活窗格平分;最小 4 MiB 且保留最新一张 | 删除最老图像;在空闲窗格扫描收敛前,受压进程最多可在目标之外为每个存活窗格保留一份 4 MiB 最新图像余量 |
| 编码图像尺寸 | 声明宽高 ≤ 2,048,像素数 ≤ 2,048² | 解码前拒绝 |
| 渲染图像尺寸 | 宽高 ≤ 1,024;BGRA8 ≤ 4 MiB | 缩放 iTerm2/kitty 图像;Sixel 解码进有界缓冲 |
| PTY 输入 | 每窗格另有固定 64 字节待发指针移动槽;UI 队列四条,每条 16 MiB;回复 FIFO 使用含帧头的 64 KiB 内存、≤32 KiB writer 输出、≤32 KiB + 4 B 读取暂存、≤32 KiB 应用回复批次载荷及 <32 KiB 解析器分派载荷(可增长向量可能保留空闲容量) | UI 拒绝时保留原字节;回复溢出到私有临时存储,不等待原生输入容量 |
| 回复溢出磁盘 | 不设固定磁盘配额;已消费前缀保留到 FIFO 文件排空 | 排空、writer 退出或窗格销毁时删除;存储错误显式终止回复交付,但输出与退出观察继续 |
| PTY 输出 | 64 个排队数据块,加一个阻塞中的发送数据块;每个由 64 KiB 读取环形缓冲支持;结构最坏值为 4.0625 MiB。在 64 位目标上每个数据块为 64 B(编译期断言),其中 16 B 是可选的读取时间戳。数据块时间戳存储小计:每个 PTY 的 64 个预留通道槽位为 1,024 B,无论是否打时间戳,另加阻塞发送方的数据块与 VT 工作线程持有的数据块各 16 B,共 1,056 B;随 PTY 释放。PTY 是否为读取打时间戳在其创建时(窗格计数器开启时)决定,并在读取线程的整个生命期内固定,是读取线程持有的一个不可变布尔值;它在布局上的占用不计入该小计 | 阻塞读取线程,由操作系统施加背压 |
| S2 回显监视 | 计数器开启时每个窗格一个:在 64 位 macOS 上测得 232 B,编译期断言 ≤ 256 B(ECHO_WATCH_MAX_BYTES),不计入窗格账本;随窗格及其工作线程句柄释放 |
大小固定;重新布防替换记录 |
| S2 回显时间线 | 每个窗口在其重绘状态中内联 104 B,其中 40 B 为已接受 tick 的元数据,64 B 为所有者槽位。每个窗口的所有者自布防起另有:1,640 B 的槽位记录,其 64 个 24 B 事件共 1,536 B(编译期断言),另加 104 B 元数据;以及 4,120 B 的洪流环形缓冲,其 256 个 16 B 条目共 4,096 B(编译期断言),另加 24 B。所有者的取走把至多 4,096 B 的洪流条目(256 × 16 B)复制进记录(32 B 的 FrozenFlood 元数据位于其元数据内,由 24 B 的向量头与淘汰元数据组成)并释放环形缓冲;移交构建至多 2,048 B 的事件(64 × 32 B),把它们、复制的条目与 88 B 的 EchoTimelineV1 移交给调用方并释放记录,App 不再保留任何内容。除编译期断言的数组外,这些大小是在 64 位 macOS 上测得的,不作保证。所有者提前结束时(重新布防、窗格离开窗口或被退役、窗口关闭)释放其环形缓冲与未冻结的记录;已冻结但尚未移交的记录保留到该窗格重新布防或被退役 |
第 65 个事件设置 overflow 并被丢弃;第 257 个洪流条目淘汰最旧的一项并记录其 loop_seq;非所有者的布防不记录任何内容 |
| 字形图集 | 每渲染器一个 BGRA8 CPU 图集:缩放 1 时起始为 1024×1024(4 MiB),缩放 2 时为 2048×2048(16 MiB),预热备用渲染器为 256×256(256 KiB),之后按翻倍增长到最大 2048×2048,16 MiB、16,384 个条目;GPU 呈现的渲染器的字形纹理尺寸相同 | 先增长;达到 2048 或条目上限时淘汰最冷的四分之一并重试 |
| 图像图集 | 默认 1×1 占位符;仅媒体活跃时使用 2048×2048 BGRA8 | 填满时跳过较早图像;连续 240 个无媒体帧后,或可渲染媒体最后一次可见 30 秒后(无需组装帧),释放为占位符 |
| Windows 软件帧 | 任一轴 ≤ 16,384;总量 ≤ 160 MiB | 拒绝创建或调整尺寸,并保留旧的有效分配 |
| 窗格命令事件 | 1,024 个事件 | 丢弃最早事件并缩小向量容量 |
| 崩溃事件历史 | 50 条记录;每条自有可变负载最多 4 KiB,其中 target 最多 256 字节;可变保留量合计最多 64 KiB | 格式化时限制大小,并按条数和字节上限淘汰最早记录 |
| Panic 文本 | dump 负载和格式化摘要各最多 4 KiB | 在 UTF-8 边界截断,标记也计入上限 |
媒体捕获暂存和已解码内联图像各自按一个共享池记账:生产解析器在
CaptureStagingPool::process_default() 中暂存,生产窗格向
InlineMediaPool::process_default() 计费,这正是这些上限覆盖整个进程的原因。
需要捕获被接纳、或需要测量接纳或预算的测试会注入私有池,而不是共用一把锁。
崩溃历史负载保留精确长度的自有字符串,不额外保留字符串空闲容量。固定记录元数据另受记录 数量限制;backtrace、串联 panic hook,以及任意生产端 formatter 内的分配都不在可变保留量 上限内。接纳与负载排除规则见日志。
内联媒体的 256 MiB 被准确称为进程目标,不是绝对上限。每个窗格都必须保留最新 图像,而单张已解码图像最多 4 MiB。因此受压时可陈述的总上限为:
256 MiB + 存活窗格数 × 4 MiB
只要 存活窗格数 × 4 MiB 仍能放进目标内,周期性空闲窗格扫描就会把总量降回
256 MiB 或以下。较大的公式既描述收敛前的边界,也在每窗格一张图像的最低需求本身
超过目标时继续作为上限。
网格约 24 MiB 的数值同样是一个共享上限,不是“回滚 24 MiB 再加可见屏幕”。
[terminal].scrollback 设置行数上限;带超链接、组合字符或非默认下划线元数据的行更大,
因此单元格数量或保留字节可能先达到上限。
滚入历史的行以紧凑形式存储。内容完全相同的行存为一段相同单元格的连续区间。其他行若末尾相同 单元格(填充)足够长,则存为截至最后一个不同于填充的单元格为止的内容,再加一个填充单元格和行宽: 该行必须保留至少两个填充列,且至少节省四分之一的存储和 256 B。200 列中 40 个字符的行从 4,800 B 降到 984 B。读取这类行的结果不变;编辑它会恢复完整的行。调整大小时若用不同于填充的 单元格补齐历史行,该行会按新宽度完整存储。滚动会复用旧行释放的缓冲,因此每滚动一行最多分配一次 行存储。
CSI 3 J 会释放活动主屏幕历史和多余的历史容器容量,不降低用户请求的历史上限或
实际配置上限。只有这次显式擦除会重置预算检查计数;普通 FIFO 行复用仍保持每 512 次
滚动的检查节奏。历史前缀删除会更新精确淘汰身份和提示符坐标,包括随主屏幕保存的提示符。
缩小列数只修复每行新右边界被截断的宽字符首格,保留紧凑游程和现有容量滞后策略,
不会为检查边界而展开整段历史。
sonicterm-resource 按所有者与 ResourceClass 跟踪计费,不持有载荷内存。
进程内治理器保存所有者树和账本;RAII 预留令牌在析构时释放计费。
生产 GUI 拓扑为:
flowchart TD
process["Process"] --> window["Window"]
window --> pane["AppPane"]
process --> retired["已退役 PtyTransport"]
每个退役 PTY 都有唯一的进程直属 PtyTransport 所有者和一个 ReaperWork 条目。
传输持有原生载荷、许可、所有者与记账额,直到全部原生阶段完成且 worker 已 join,
或者将它们一起转入 UnresolvedSink。退役传输不会让原窗口或窗格所有者保持开放。
ReaperWork 在生产中实际计费,但不进入窗格接缝上限,因为计费属于退役传输。
一个 App 所有的管理器最多接纳 256 个任务单元,包括预留、保留任务和 sink 条目。 Windows 使用 20 个 helper 槽位和 2,048 个原生句柄许可;Unix 使用 12 个 helper 槽位和 768 个描述符许可。一个单元在 Windows 预留八个句柄,在 Unix 预留三个描述符。 开始执行时,Windows 单元一次申领五个 helper 槽位,Unix 单元申领一个;重试和运行中的 worker 继续持有整组 grant。计数表示持有的资源,不只是正在运行的线程。
接纳拒绝不会丢弃所有权。无槽位关闭重试一次,再明确采用同步回退;它不享有预留路径的
调用方快速返回保证。sink 条目持有容量直到进程退出,因此 QueueFull 可能持续到本次
进程结束。终态释放保留未完成的原生载荷和记账,而不执行不安全的析构。
类型系统还定义了 SharedFont、SharedRaster、SharedAtlas、LocalPty 和 mux
所有者种类,但 GUI 不注册这些节点。
所有者 id 单调递增且永不复用。合法父子组合取决于 ProcessKind,创建时会检查。
所有者状态从 Open 变为 Closing,再变为 Closed;进入 Closing 后不再接纳新子节点
和新预留,最终关闭要求没有存活子节点和记账额。
窗口插入与其所有者注册是同一个操作。共享拓扑完成步骤会注册主窗口和子窗口中的无所有者
窗格,每次 30 s 保留量扫描也会协调它们。标签页转移先准备目标窗格所有者,通过一次原子的
transfer_many 移动所有转移窗格的全部现有计费,再替换守卫并关闭已清空的源所有者。即使
解析器锁被占用,进程和分类总量也不变。拒绝时释放临时所有者,完整恢复源标签页、原有计费和
存活 PTY,之后才可能执行源窗口回收。
窗口注册失败时,该窗口仍可在层级记账之外使用。只有没有非零计费的窗格才能进入这种未注册 状态;已计费标签页不能在转移时悄悄丢失记账。只要窗口具有所有者,失败的窗格注册仍可重试。
每个接缝(即网格、解析器或 PTY 队列这样的所有权边界)负责执行自己的上限。GUI 治理器的进程和按类别上限为无限,窗口所有者也只用于 跟踪。这样不会再维护一套可能与实际分配代码漂移的进程级限制。
每个 AppPane 所有者仍有一个已提交字节绊线。类型化的
pane_seam_cap_terms() 清单让每个实际计费的窗格类别恰好出现一次。可见区、历史区与已保存
主屏幕共用同一个网格上限,因此由 GridVisible 携带该值,GridHistory 与
GridAlternate 携带零;ParserCapture 同时携带两个解析器上限;PTY 输入的队列上限只计一次:
PANE_SEAM_CAP_SUM_BYTES = sum(pane_seam_cap_terms().bytes)
PANE_COMMITTED_BUDGET_BYTES = 2 × PANE_SEAM_CAP_SUM_BYTES
系数 2 为分配器容量、摊销过冲和最新图像余量留出空间。它用于发现某个接缝已经停止
设限或少报保留量,不是正常分配的第二套策略。每次保留量扫描通过失败原子的 try_resize
结算已有计费,包括字节和条目反向变化的情况。准入检查最终替换量,而不是中间峰值。
任一维增长都要求祖先开放;纯减少可在关闭期间结算。拒绝采样时保留旧计费,因此总账可能
落后于实际保留量,直到后续采样成功。快照只供观察,不是全局线性化的总量。
单个窗格报告包含八个互不重叠的接缝:
| 字段 | 所属内存 |
|---|---|
grid_visible_bytes |
可见行、提示符存储和稀有单元格属性 |
grid_history_bytes |
保留的回滚行,每行按实际存储的单元格计费(截断行的前缀加一个填充单元格) |
grid_alternate_bytes |
备用屏幕活跃时保存的主屏幕 |
parser_bytes |
传输中的转义序列和媒体捕获缓冲 |
hyperlink_bytes |
驻留的 OSC 8 字符串(每个不同的 URI 一次分配,其下每个客户端 id 一次分配)及查找表 |
inline_media_bytes |
窗格保留的已解码图像像素 |
pty_output_bytes |
排队 PTY 输出固定的环形缓冲内存 |
pty_input_bytes |
排队输入向量 |
total_bytes 是八项之和,largest_seam 指出最大项。session retention 行会对所有
已采样窗格汇总同样字段。
为性能检查点采集的 memory snapshot 行包含同样字段,另加四个标注:checkpoint_index、
checkpoint_label、checkpoint_attempt 与 checkpoint_complete(没有窗格被锁占用且每个窗格都已采样)。
采集它不会改变周期性采样所做的任何事:不运行保留量处理、回收或裁剪,也不重置采样节奏。在带裁剪钩子的构建中,它还包含 trimmed、trim_source 与 trim_seq。
渲染器内存单独报告,因为它属于窗口而不是窗格:
-
glyph_atlas_bytes:CPU 字形图集像素容量加上脏矩形列表容量,因此会随图集增长而上升; - 每个渲染器在
total=之后附加:glyph_atlas_dim、glyph_atlas_packed_pixels、glyph_atlas_growths、glyph_atlas_evictions、glyph_atlas_fit和glyph_atlas_max_tile。fit 是 256、512、1024 与 2048 中能放下常驻图块并保留四分之一高度空余的最小值。否则为no_headroom(每个图块都能在 2048 放下,但没有尺寸能留出这四分之一)、does_not_fit(某个图块即使在 2048 也放不下)或evicted(图集发生过淘汰,常驻集合已不再是工作集)。glyph_atlas_growths统计渲染器自构建以来的翻倍次数,重置不会清零; -
image_atlas_bytes:CPU 内联图像图集容量; -
row_glyph_cache_bytes/row_glyph_cache_items:缓存的字形记录、下划线段、缺字方框和 缺失字符的负载,加上跟踪存储(表、行位置向量与固定列表),以及缓存行数。每个渲染器的负载 不超过 448 MiB,跟踪存储不超过 64 MiB; -
row_quad_cache_bytes/row_quad_cache_items:哈希表后备存储、缓存背景/装饰 quad 向量和缓存行数; -
software_frame_bytes:Windows CPU/GDI 帧,其它平台为零; -
row_ink_bytes/row_ink_items:渲染器的RowInk部分,计入renderer_total_bytes: 每个可见行一条墨迹记录(该行上次绘制的范围),加上一帧的暂存缓冲。一帧呈现时剪除已关闭窗格与 已消失行的记录,表内条目不足四分之一时收缩。该分类只报告、不计费,覆盖数值为 144 MiB (按桶取整的表条目为最大可见单元数的两倍,加上一帧暂存); -
vertex_scratch_bytes/vertex_scratch_items:渲染器的UploadStaging部分,计入renderer_total_bytes。它是呈现管线复用的 CPU 顶点组装缓冲,加上字形图集与图像图集两个上传 各自的脏矩形列表、合并矩形列表和暂存缓冲。顶点缓冲每帧清空后重新填充。一帧之后,若容量超过 该帧顶点数的四倍且超过 1 MiB,就收缩到用量的两倍;未产生任何顶点的帧会完全释放超过 1 MiB 的 缓冲。每个上传在一次同步后清空两个矩形列表,并把超过 1,024 个矩形的列表收缩到 64。暂存缓冲 在一次同步期间至多保存一整张图集;每次 wgpu 同步之后,它按该次同步的最大一次写入遵循顶点缓冲的规则,遮挡窗口裁剪会完全释放它。条目数只统计顶点缓冲:它持有分配时为 1。渲染器 释放时一并释放全部。该分类记录的覆盖数值 34.5 MiB 是上传包络:两个 16 MiB 暂存缓冲,加上一次 同步期间矩形列表的 2 个上传 × 2 个列表 × 2 × 16,384 个矩形 × 20 字节。顶点缓冲在其旁实时报告, 没有固定上限,因为它跟随每帧的顶点数; -
frame_scratch_bytes/frame_scratch_items:渲染器的FrameScratch部分,计入renderer_total_bytes。它保存一次组装填充的逐帧绘制向量(字形、quad、叠加层字形与 quad、图像、 行范围、下划线、下划线归属、暂存范围、缺字方框、窗格矩形、列边界与行键),在已组装帧之间保留。 每次归还时,每个向量都先清空,再限制在其上限内:字形与 quad 各 4 MiB;叠加层字形、叠加层 quad、 图像、行范围、下划线与缺字方框各 1 MiB;窗格矩形与暂存范围各 64 KiB;下划线归属与行键各 256 KiB; 列边界合计 1 MiB,先丢弃最大的槽位。只有完成的组装才会在容量超过用量四倍且超过 1 MiB 时把向量 收缩到用量的两倍,并丢弃超出本次峰值的列边界槽位。失败或重试的帧用量低估了整帧,因此保留其已预热 的容量。该分类的覆盖数值为它们之和,16,384,000 字节。未变化或无操作的帧不取用暂存,也不 释放任何内容。条目数为持有分配的向量数;帧持有暂存期间该数值为零; -
chrome_cache_bytes/chrome_cache_items:渲染器的ChromeCache部分,计入renderer_total_bytes:64 槽标签标题表与 32 槽界面文本段表(首次使用时分配)、每个保留标题的 键文本、绘制文本与字形、每个保留界面文本段的一份文本与字形,以及保留的界面调色板颜色字符串。 标题或文本段只在不超过 256 字节文本与 512 个字形时保留。调色板只在其颜色字符串合计不超过 4 KiB 时保留;字符串合计更多的主题每次请求都重新派生且从不保留,因此保留的字符串从不超过该余量。该分类的 覆盖数值 1,626,560 字节是两张表都装满最大条目,再加这 4 KiB。条目数为保留的标题数与文本段数之和。
这些都是主机内存副本。GPU 纹理与缓冲不在其中,因为显卡驱动拥有它们,wgpu 也不提供
大小。行缓存报告按已分配的哈希表与嵌套向量容量计算,而不是按当前长度。普通 clear/retain
后表容量具有粘性;窗格离开渲染器时,SonicTerm 会在同一个事件循环操作中先删除该窗格的
字形行,再删除 quad 行,保留其它窗格的条目并请求压紧表。嵌套负载和条目数会立即下降,
但表分配器可以保留当前 bucket 档位。报告会列出所有可见和预热渲染器。
live_renderers 来自独立的进程级计数器;若该计数大于可列出的渲染器集合,说明有一个
仍存活但已无法从窗口拓扑访问的渲染器。
这些字段不是渲染器整个堆的清单。渲染器保存在帧暂存中的逐帧绘制向量会被保留,并在
frame_scratch 下报告。帧键元数据、临时帧计划、逐帧窗格视图、逐行与逐段的塑形缓冲以及其它
未列出的主机分配仍不计入 renderer_total_bytes;操作系统进程读数还包含已计费分类以外的内存。
搜索打开期间,SearchState 会保留已准备好的匹配器,正则模式下包括其编译后的正则表达式;
搜索关闭,或查询、模式、大小写设置改变时,该匹配器会被释放,资源治理器不对这部分内存计费。
在窗格接缝之外,App 的前台探测映射对每个存活窗格最多保存一个条目和一个结果,随窗格一起释放;
worker 线程最多一个,以 live_fg_probe_workers 报告。
开启帧计数器时,守卫关联每个窗格日志估计占用 789,248 B:32,768 条分段记录(768 KiB)、64 个放弃条目和
64 个丢失区间,另加日志本身在其 Arc 中的 256 B(窗格 id、互斥锁与状态,在 64 位 macOS 上测得)。
每个 App 持有一个估计 525,464 B 的跨度存储:16,384 个跨度(512 KiB)、64 个丢失区间,以及存储在其 Rc
中的 152 B(含 RefCell 借用状态)。估计值不含注册表向量的容量、每个窗格保留的句柄以及分配器开销。
提取会在交换之前分配一套替换缓冲区,因此被提取的缓冲区与替换缓冲区会同时存在,直到调用方丢弃该次转移。
已关闭窗格的日志在某次提取将其剪除、且其工作线程丢弃自己的句柄之后释放。每次计数收集把 440 B 的跨度记录放在栈上。
这些都不计入任何账本所有者,也不出现在内存采样中。关闭计数器时不分配任何记录缓冲区,也不读取关联时钟、
不获取关联锁,但 Option 字段以及更大的保管与来源类型仍占用其布局。harness 的传输原地序列化一次提取的缓冲区,
因此写入旁路文件期间,进程持有提取的缓冲区、App 的替换缓冲区和一个 64 KiB 写入缓冲区,不复制任何记录。
渲染器的保留量不计入任何账本所有者。空闲图像图集被释放时,渲染器的
retained_amounts().image_atlas 立即从 16 MiB 降到 4 B;聚合的 renderer_total_bytes 在下一次
内存采样(每 30 秒一次)时显示这一下降,每个窗格的 InlineMediaRetained 计费保持不变。
把日志级别设为 info,最多每 30 s 得到一条 memory snapshot:
[logging]
level = "info"这是顺序执行的诊断采样,不是可线性化的单一时刻快照。每个窗格的解析器、内联媒体和
PTY 队列分别读取;各窗格、渲染器、共享分配器及操作系统内存也依次采样。
即使 panes_contended=0,这些读数也不是同时取得的,采样计费更不是分配时的准入上限。
该行合并:
- 操作系统给出的
process_private_committed_bytes、process_resident_bytes、process_virtual_bytes及其变化量; - 会话总量和全部八个窗格接缝;
-
panes_total、panes_sampled、panes_contended; - 渲染器总量、角色和
live_renderers; -
live_fg_probe_workers,即该 App 的前台探测 worker 线程数; - 一次共享设备分配器读数。
process_virtual_bytes 是保留地址空间,不是实际占用。GPU 进程可能保留数百 GB 地址空间,
但并未常驻同等内存。应把 resident/private 数据与 session_total_bytes、
renderer_total_bytes 对照。
没有数值时会明确说明原因:
| 取值 | 含义 |
|---|---|
unsupported |
平台或后端不提供该数据 |
unavailable |
没有可比较的上一次采样 |
panes_contended=N |
N 个窗格因解析器或内联图像锁被占用而跳过,会话总量不完整 |
allocator_state=none |
没有渲染器,因此没有查询分配器 |
macOS 的私有/已提交内存为 unsupported;SonicTerm 会报告常驻与虚拟内存,
但不会拿虚构值替代 phys_footprint。Windows 的私有/已提交内存是 PrivateUsage,
常驻内存是 WorkingSetSize。Linux 与其它没有进程内存采样器的平台会把三项操作系统
数据都报告为 unsupported;窗格、渲染器和分配器记账仍会运行。
分配器按共享设备/上下文只采样一次,来源优先为主渲染器,否则使用确定性的可见或 预热回退。所有窗口(包括通过新建窗口打开的窗口)都经由该设备渲染,因此这一次读数 覆盖全部窗口。可测量报告包含:
allocator_allocated_bytes
allocator_reserved_bytes
allocator_allocations
allocator_blocks
allocator_largest_block_bytes
软件适配器在 wgpu 30 中使用 MemoryHints::MemoryUsage,硬件适配器使用
MemoryHints::Performance。D3D12 上,软件策略把初始分配器块从设备 128 MiB / 主机 64 MiB 改为
设备 8 MiB / 主机 4 MiB。这些只是放置与块大小提示,不是分配上限;
更大的资源仍可分配。
原生遮挡持续 30 秒的窗口会交还其渲染器能够重建的内容。保留量处理每 30 秒对每个窗口检查一次, 因此裁剪发生在遮挡后 30–60 秒,没有自己的计时器或唤醒。它在记账和快照之前运行,并且不受任何日志 门控限制,因此在默认日志级别下同样发生。已在本次遮挡期间裁剪过的窗口、已停放的窗口、设备已停止或 拒绝工作的窗口,以及预热备用窗口都会被跳过。仅后端报告的遮挡不会开始 30 秒计时。
裁剪在设备门控内释放:保留的帧纹理,在 GPU 呈现器上降为 1×1(软件呈现器的帧纹理本来就是 1×1); 两个呈现缓冲,恢复到初始的 4,096 个 quad,以及顶点暂存;行字形、行 quad 与行墨迹缓存;两个图集上传 的暂存缓冲和矩形列表;持有的帧暂存(已借出的会在租约归还时丢弃);标签标题与文本段表,保留调色板; 以及在没有可见媒体时已提升的图像图集。它保留字形图集及其 GPU 纹理、待处理的图集重试及其淘汰状态、 Windows 软件帧和预编辑缓存。拒绝该工作的设备不发生任何变化。下一帧是完整的首帧,其余内容按正常 路径重新增长;恢复可见会清除裁剪标记。
渲染器部分只报告、不进入账本,因此裁剪会降低同一次处理快照中的 renderer_total_bytes,从不改变
窗格的记账。每个渲染器条目还报告 renderer_trimmed 与 renderer_gpu_released_requested_bytes:裁剪交还的帧纹理和
呈现缓冲,是请求大小而非常驻量,且不计入总量。
窗口可见时呈现缓冲也会收缩:每个 600 次绘制(包括空绘制)的窗口结束时,如果容量超过该窗口峰值用量的四倍且超过 初始的 4,096 个 quad,两个缓冲都会按峰值两倍向上取 2 的幂重建,不低于 4,096 个 quad。
设置 debug 后可查看按窗格和按渲染器的行:
[logging]
level = "debug"30 s 扫描使用 try_lock,绝不等待窗格解析器或内联图像锁。注册、协调、记账、停滞捕获取消和空闲
媒体回收在所有日志级别下都会运行,只有日志输出受级别控制。仅用于采样的唤醒不会请求重绘。
两种回收会移除用户可见内容,因此即使在默认 warn 级别也写入
memory::reclaimed 日志目标:
grep 'memory::reclaimed' ~/.sonicterm/logs/sonicterm.log*| 消息 | 含义 |
|---|---|
cancelled a media capture that stopped receiving |
连续两个 30 s 周期没有字节到达;已释放暂存,该图像不会显示 |
discarded inline images from idle panes |
从仍持有较少窗格时期份额的窗格中删除了较早图像 |
单个偏大快照不能证明持续增长。应比较连续多次采样。grid_history_bytes 上升指向回滚;
inline_media_bytes 上升指向图像;parser_bytes 连续多次保持较高说明有传输尚未结束。
panes_contended 非零表示聚合值低估了会话。
| 主题 | 主要路径 |
|---|---|
| 治理器、账本、预留 | crates/sonicterm-resource/src/{ledger,owner,reservation}.rs |
| 资源契约与所有者种类 | crates/sonicterm-types/src/resource.rs |
| 窗格限制与所有者注册 | crates/sonicterm-app/src/app/{mod,owners}.rs |
| 窗格测量、记账、回收 | crates/sonicterm-app/src/app/retention.rs |
| 聚合快照 | crates/sonicterm-app/src/app/memory_snapshot.rs |
| 内联媒体上限 | crates/sonicterm-app/src/app/media.rs |
| 网格与超链接上限 | crates/sonicterm-grid/src/{grid,hyperlink}.rs |
| 解析器捕获上限 |
crates/sonicterm-vt/src/vt.rs、crates/sonicterm-vt/src/vt/staging.rs
|
| PTY 队列上限 | crates/sonicterm-io/src/pty.rs |
| 渲染器保留量与分配器报告 | crates/sonicterm-gpu/src/core.rs |
| 守卫关联记录(仅帧计数器) | crates/sonicterm-app/src/app/guard_correlation.rs |