Replies: 1 comment
|
这份取样很有价值 —— 页面侧常驻内存没有淘汰路径客户端对会话转录只做追加,没有任何淘汰:
也就是说:每一页加载过的历史、以及每一条流式事件提交进转录的节点,都会一直留在 一个会把情况放大的交互#6325(思考过程无法折叠)的现有社区方案 我没有做的,以及为什么我没有在真实浏览器里复现这次泄漏,因此不会声称定位到了某个确定的泄漏点。 要定位到可修复的点,建议下一步这样测(能直接区分两类原因):
修复落点方向无论上面是哪一类,落点都在客户端转录的驻留策略上:给已加载窗口加淘汰 如果你愿意把两份 Heap Snapshot 的对比贴出来,我可以帮着定位到具体对象。 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
一、问题概述
dsh web前端在长时间、持续流式输出的会话中,页面渲染进程内存单向累积,实测 5 小时后达到 9.4G 物理占用(峰值 13.7G),并伴随渲染进程主线程长期 100% 占用、GC 抖动。刷新页面可回收内存,说明是页面侧堆累积,而非服务端。同一台机器上,dsh 服务端(node 进程)占用仅 426MB 且平稳,问题完全位于前端页面。
二、环境
dsh web --port 6010 --no-open)http://127.0.0.1:6010/(dsh web GUI)三、取样证据(
/usr/bin/sample,2251 样本 × 1ms ≈ 2.25s 窗口)采样头部:
3.1 主线程全程 100% 忙,且 86.8% 落在「处理 WebSocket 流式消息」这条链上
3.2 JIT JS 内部:疯狂分配对象 + 反复 GC(堆大且几乎全是存活对象)
JSC::LocalAllocator::allocateSlowCaseJSC::JSFinalObject::visitChildrenJSC::MarkedBlock::Handle::sweepJSC::JSCellButterfly::visitChildrenmadviseJSC::JSObject::visitChildrenJSC::SlotVisitor::drainJSC::IncrementalSweeper::doSweepJSC::EdenGCActivityCallback::gcTimeSliceWTF::WeakHashSet<WebCore::EventLoopTaskGroup>::add对比:布局/绘制仅约 2%(
WebCore::RenderBlock::paint递归计数 44)。CPU 主要烧在 JS 对象分配与 GC 上。3.3 疑似不可变状态「整树复制 + 冻结」痕迹
调用链中出现:
JSC::globalFuncCopyDataProperties(对象展开/Object.assign式浅拷贝)JSC::objectConstructorIsFrozen/JSC::objectConstructorFreeze(递归冻结)JSC::JSObject::getOwnPropertyNames/JSC::Structure::getPropertyNamesFromStructureJSC::JSObject::putOwnDataPropertyBatching即每条流式事件都可能在整棵会话状态树上做一遍拷贝 + 冻结,成本随会话增长而增长。
四、复现(现场实测,非推测)
同一环境、全新启动的应用,仅持续一个正常会话(对话流式输出):
复现要点:一个包含大量长工具输出(数十 KB
MB 级文本)的会话,持续流式对话 1030 分钟即可稳定观察到渲染进程内存单向抬升。五、怀疑方向(供上游定位参考)
copyDataProperties+freeze+getOwnPropertyNames组合与之吻合;事件频率高(每秒数百条 WS 消息)× 状态树大 → 分配量与 GC 压力随会话增长。六、影响
七、期望
八、附件
“JF-Harness Web Content”的取样.txt:sample原始输出(9.4G 现场,pid 78054)。All reactions