You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Direct2D/DirectWrite更新文本时每次调用CreateTextLayout都需释放吗

DirectWrite TextLayout内存管理问题解答

两种场景内存表现差异的原因

  • IDWriteTextLayout是标准COM对象,遵循COM引用计数规则:所有通过IDWriteFactory::CreateTextLayout工厂方法返回的COM接口指针,调用方都持有对象的强引用,必须主动调用Release()释放所有权,否则必然产生内存泄漏。
  • 第一种场景你观察到内存稳定并非真的没有泄漏,大概率是两类原因:
    1. 你使用了WRL::ComPtr这类智能COM指针管理TextLayout对象,每次给智能指针赋值新创建的对象时,智能指针会自动调用Release()释放上一个旧对象,所以你不需要手动写释放逻辑也不会泄漏
    2. 你的CalculateFrameStats实际调用频率远低于每帧,内存增长速度极慢,短时间观测不到明显涨幅,并不是真的不存在泄漏
  • 第二种场景创建逻辑移到每帧执行的3DFrameDraw中,你没有用智能指针也没有手动Release,每帧都会产生一个新的无人释放的TextLayout对象,自然表现为持续的内存增长。

文本更新时的正确处理方式

是否需要每帧释放取决于你选择的实现方案:

  1. 每帧重建方案(推荐用于频繁变化的文本,比如FPS、实时参数)
    每帧调用CreateTextLayout创建匹配当前文本的布局对象,调用DrawTextLayout绘制完成后立刻调用Release()释放即可,该方案实现简单,创建TextLayout的性能开销极低,完全不会影响常规3D场景的帧率。
  2. 复用对象方案(推荐用于格式固定、更新频率低的文本)
    如果文本的字体、字号、最大布局宽高等参数固定,不需要每次重建布局对象,可以在初始化阶段创建一次IDWriteTextLayout对象,后续文本更新时直接调用IDWriteTextLayout::SetText()方法修改文本内容即可,不需要反复调用CreateTextLayout,对象只需要在程序退出前统一释放一次即可,性能比每帧重建更好。

注意:如果使用复用方案,修改文本后如果需要调整对齐方式、字体属性、布局范围等参数,直接调用IDWriteTextLayout对应的Set方法修改即可,不需要重建对象。

内容的提问来源于stack exchange,提问作者Bill Banks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:45:00