ASP.NET Core 5.0使用EvoPDF转PDF偶发OutOfMemory异常如何解决
问题根因说明
你观测到的应用内存占用200-400MB是.NET托管堆的统计值,EvoPDF的HTML渲染逻辑大量依赖非托管内存,这部分资源消耗不会计入托管内存统计,所以你排除物理内存不足的结论是对的,但问题实际出在非托管资源的分配或释放环节。
排查方向
- 检查EvoPDF版本适配性:迁移到.NET 5后如果继续使用旧的.NET Framework专属版本,会出现非托管内存泄漏的偶发问题,该版本对.NET Core/IIS集成管道的适配存在缺陷。
- 检查IIS应用池配置:确认应用池是否开启了「虚拟内存限制」「专用内存限制」,这类限制会约束进程的总内存占用(含非托管内存),触达上限后内存分配会失败;另外要确认「加载用户配置文件」选项是否开启,EvoPDF依赖用户配置下的临时目录权限,未开启时临时文件写入失败会抛出误导性的OOM异常。
- 检查并发请求峰值:开发环境并发量低无法复现,生产环境如果瞬时有大量PDF转换请求,多个EvoPDF实例的非托管内存累计峰值超过进程可用地址空间时就会触发该错误。
- 检查临时目录权限:确认IIS应用池运行身份对系统临时目录有读写权限,临时目录所在磁盘剩余空间是否充足,临时文件写入失败也会被EvoPDF识别为内存不足。
可行解决方案
- 释放EvoPDF非托管资源
你当前的代码没有释放HtmlToPdfConverter实例,该实例包装了大量非托管资源,必须用using包裹,修改后代码如下:
using (var evo = new EvoPdf.HtmlToPdfConverter()) { // 其他配置逻辑 using (var stream = new MemoryStream()) { string baseUrl = ""; evo.ConvertHtmlToStream(html, baseUrl, stream); return stream.ToArray(); } }
未释放的实例会导致非托管内存持续累积,多次调用后就会偶发分配失败。
升级EvoPDF版本
更换为专门适配.NET Core 3.0+/NET 5+的EvoPDF版本,同时在服务器上安装对应版本的VC++ Redistributable运行库,EvoPDF底层依赖该运行库,版本不匹配会出现偶发资源分配错误。优化EvoPDF配置
添加以下配置降低渲染阶段的内存占用:
// 减少不必要的渲染等待时长 evo.ConversionDelay = 1; // 开启自动图像缩放减少内存占用 evo.ImagesScalingEnabled = true; // 用自动触发模式避免资源积压 evo.TriggerMode = TriggerMode.Auto; // 显式指定有权限的临时目录,避免默认目录权限问题 evo.TempFilesPath = @"C:\自定义临时目录路径(需给应用池身份开读写权限)";
- 调整IIS应用池配置
打开应用池高级设置做以下修改:
- 将「加载用户配置文件」设为
True - 将「虚拟内存限制」「专用内存限制」设为0(表示无限制)
- 适当调大应用池队列长度,避免瞬时并发请求被强制回收资源
- 增加异常重试机制
针对该特定OOM异常添加最多3次的重试逻辑,每次间隔100ms,绝大多数瞬时资源抢占导致的异常重试后即可正常执行。
内容的提问来源于stack exchange,提问作者MiVoth
相关产品推荐
相关产品推荐

