Skip to content

Commit ed2e656

Browse files
committed
fix(capture): 限制关键帧 base64 内存保留,修复长时间采集内存无界增长
SmartSampler.keyframes 在整个会话期间无界持有全部关键帧的 imageBase64(单帧数百 KB,1h 约 240 帧累积数十 MB 不释放,仅 reset 才清空),是内测反馈内存占用 5GB 的重要诱因。现仅保留最近 30 帧的 base64,更早帧剥离为空串(元数据保留、图片已由 keyframe_save 增量落盘),与既有'分析后清空 base64'策略一致。
1 parent 4411656 commit ed2e656

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

‎client/src/lib/capture/smartSampler.ts‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ const DEFAULT_CONFIG: SmartSamplerConfig = {
4040
const HASH_DUP_THRESHOLD = 5;
4141
/** 渐进板书帧(变化触发且 0 < score < 0.3)收紧阈值:距离 ≤ 2 才跳过,避免漏采渐进内容 */
4242
const WRITING_HASH_DUP_THRESHOLD = 2;
43+
/**
44+
* 内存上限:仅最近 N 个关键帧保留 imageBase64,更早的剥离为空串。
45+
* 单帧 base64 可达数百 KB,长时间采集(1h 约 240 帧)若无界持有会
46+
* 在渲染进程累积数十 MB 且不释放(仅 reset 才清空)。更早帧的图片
47+
* 已由 keyframe_save 增量落盘,元数据(id/timestamp/changeType)保留。
48+
*/
49+
const MAX_IMAGE_KEYFRAMES = 30;
4350

4451
// ================================================================
4552
// SmartSampler
@@ -140,6 +147,10 @@ export class SmartSampler {
140147
this.keyframes.push(keyframe);
141148
this.lastCaptureTime = now;
142149
if (hash !== null) this.lastFrameHash = hash;
150+
151+
// 内存上限:剥离过早关键帧的 base64(已落盘),避免长时间采集内存无界增长
152+
this.trimOldKeyframeImages();
153+
143154
return keyframe;
144155
}
145156

@@ -155,6 +166,21 @@ export class SmartSampler {
155166
this.lastFrameHash = null;
156167
}
157168

169+
/**
170+
* 剥离过早关键帧的 imageBase64(保留元数据),将内存占用控制在
171+
* MAX_IMAGE_KEYFRAMES 帧以内。用新对象替换避免突变已发射的事件引用。
172+
*/
173+
private trimOldKeyframeImages(): void {
174+
const n = this.keyframes.length;
175+
if (n <= MAX_IMAGE_KEYFRAMES) return;
176+
const cutoff = n - MAX_IMAGE_KEYFRAMES;
177+
for (let i = 0; i < cutoff; i++) {
178+
if (this.keyframes[i].imageBase64) {
179+
this.keyframes[i] = { ...this.keyframes[i], imageBase64: '' };
180+
}
181+
}
182+
}
183+
158184
// ================================================================
159185
// 私有方法
160186
// ================================================================

0 commit comments

Comments
 (0)