ClipHost 剪贴板窗口频繁白屏——GDI/USER 对象耗尽导致 WPF 渲染失败

BUG反馈 · 43 次浏览
钐钐shanshan 创建于 5天7小时前

以下内容由AI整理

现象

  1. ClipHost 进程后台运行约一天后,打开剪贴板窗口(clip toggle)大概率白屏;
  2. 白屏时窗口实际可正常交互(点击、滚动、聚焦均有效)——WebView2 内容层仍在运行,只是宿主 WPF 窗口的视觉层没有呈现;
  3. 调整窗口大小后立即恢复正常显示;
  4. 重启 ClipHost 进程后恢复,但若干小时后必定复发。

环境信息

  • Windows 11 专业版(10.0.22631)
  • IntelliTools.ClipHost 0.30.56.0(FileVersion 0.30.56.0,ProductVersion 0.30.56.0+2449798d)
  • .NET 10.0 桌面运行时 / WebView2 Runtime 153.0.4234.48
  • 内存 32 GB(问题发生时仍有约 9 GB 可用)/ Intel 核显
  • 通过 Quicker 动作发送 clip toggle 触发

关键证据

1. 宿主日志(Ceastld\logs\cliphostYYYYMMDD.log)每次显示窗口时都记录 dispatcher 未处理异常,形态固定:

code
 
[FTL] : ClipHost dispatcher unhandled exception
System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
at System.Windows.Interop.HwndTarget.OnShowWindow(Boolean enableRenderTarget) ← 显示窗口时
at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam) ← 移动/改尺寸时
at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(...)

2. 进程资源实测(问题发生时):

  • GDI 对象 10000/10000、USER 对象 10001/10000 —— 双双达到会话上限
  • 同时系统内存充足(可用 ~9 GB)、进程工作集仅 216 MB、句柄 1002、线程 28 → 排除真实内存耗尽。GDI 配额耗尽时,WPF 创建渲染目标的底层分配失败,就会抛出这种“假 OOM”。

3. 异常统计(连续三天日志):

日期 FTL 次数 首次出现
09-20 98 15:58
09-21 237 10:44
09-22 102 10:48(截至 14:33)
  • 每天的首次 FTL 恰好是当天第一次 clip toggle(可与 better-clip*.log 前端 verb 日志逐条对齐);
  • 此后每次开关窗口触发 3~7 条 FTL(WM_SHOWWINDOW / WM_WINDOWPOSCHANGED 一连串窗口消息全部失败);
  • 当日堆栈分布:UpdateWindowSettings ×100、UpdateWindowPos ×68、OnShowWindow ×32、OnResize ×2、DUCE.Channel.SyncFlush ×2 —— 全部集中在窗口显示/布局变更时建立渲染目标的路径。

原因分析(供参考)

ClipHost 存在 GDI/USER 对象泄漏,随运行时长累积(约一天到 10000 上限)。窗口为隐藏/显示复用模式、WebView2 使用透明背景(DefaultBackgroundColor),显示窗口时 WPF HwndTarget 需重建渲染目标,此时 GDI 对象已满 → 创建失败 → 白屏;调整大小会再次触发 UpdateWindowSettings,恰逢配额抖动出空位而成功 → 立即恢复。这与“白屏但可交互、改大小即恢复、经常而非每次”的全部症状吻合。

排查建议

  • 用任务管理器“GDI 对象”列或 Process Explorer 观察 ClipHost 进程 GDI/USER 计数随时间的增长曲线,可确认泄漏速率与触发场景(每次显示/隐藏窗口?图标加载?);
  • 常见泄漏点:每次显示/隐藏窗口时创建而未释放的 GDI 对象(位图/画刷/区域/字体)、Icon.FromHandle 后未 DestroyIcon、分层透明窗口资源的反复重建等。

临时缓解(用户侧)

  • 重启 ClipHost 进程(GDI 归零,可维持约一天);
  • 白屏时拖动窗口边缘调整大小即可单次恢复。

回复内容
暂无回复
回复主贴