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

.NET 8 + iText pdfhtml转换PDF时内存泄漏问题求助

.NET8 + iText7.pdfhtml 5.0.3生成大PDF内存暴增且无法回收问题排查建议

问题背景

我们的PDF生成程序支持1~1000+页的文档输出,在.NET6 + iText7.pdfhtml 4.0.2版本下运行正常。但升级到.NET8 + iText7.pdfhtml 5.0.3后,出现严重内存异常:

  • 调用HtmlConverter.ConvertToPdf(html, pdfDocument, properties);时,内存占用随PDF页数增长急剧上升
  • 生成完成后内存无法释放,IIS服务器中这些内存停留在Generation 2堆,GC无法回收,最终导致服务器内存耗尽、应用池被迫重启
  • 通过NetBrains分析定位到,内存占用的核心源头是iText.Layout.Borders中的set_Capacity方法尝试分配28GB内存,Generation 2堆全程持续增长,GC无法有效缩减内存。

核心生成代码如下:

if (!string.IsNullOrEmpty(html))
{
    using (var workStream = new MemoryStream())
    using (var pdfWriter = new PdfWriter(workStream))
    {
        var watermark = isDraft ? "DRAFT" : string.Empty;
        ConverterProperties properties = new ConverterProperties();
        PdfDocument pdfDocument = new PdfDocument(pdfWriter);
        if (landscape)
            pdfDocument.SetDefaultPageSize(PageSize.A4.Rotate());
            PdfDocEventHandler handler = new PdfDocEventHandler(formDocument.ConfirmationID, formDocument.SubmittedDate, watermark);
            pdfDocument.AddEventHandler(PdfDocumentEvent.END_PAGE, handler);
            HtmlConverter.ConvertToPdf(html, pdfDocument, properties);
            pdfOut = AddPageNumbers(workStream.ToArray(), formDocument.ConfirmationID, formDocument.SubmittedDate);
    }
}

可能原因

  1. iText7.pdfhtml 5.x版本的边框布局逻辑存在缺陷,处理大文档时,边框相关集合类错误计算容量,导致超大内存申请
  2. .NET8的GC回收策略调整与iText新版本的内存管理逻辑不兼容,导致本该回收的对象被长期持有
  3. 自定义的PdfDocEventHandler可能存在未释放的强引用,导致PdfDocument或关联大对象无法被GC回收

解决方案建议

  • 版本回退验证:暂时回退到iText7.pdfhtml 4.0.2版本,确认问题是否由新版本引入,排除.NET8本身的影响
  • 优化ConverterProperties配置:
    • 启用临时文件存储,避免全内存处理:properties.SetTempDir(new FileInfo(@"C:\your-temp-path"))
    • 禁用不必要的CSS特性,比如使用默认CSS应用工厂:properties.SetCssApplierFactory(new DefaultCssApplierFactory())
  • 检查事件处理器:排查PdfDocEventHandler的实现,确保没有持有PdfDocument或其他大对象的强引用;将处理器改为using块内的局部变量,确保资源能被及时释放
  • 临时缓解策略:在using块结束后,尝试强制触发Generation 2回收(仅作临时缓解,不推荐长期依赖):
    GC.Collect(2, GCCollectionMode.Forced, true, true);
    GC.WaitForPendingFinalizers();
    
  • 提交官方Issue:将内存分析快照、复现代码提交到iText官方仓库,确认是否为已知Bug或版本兼容性问题
  • 拆分大文档生成:对于1000+页的超大文档,拆分HTML为多个片段,分批次生成PDF后再合并,降低单次内存占用

内容的提问来源于stack exchange,提问作者Dan Williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:52:35