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

Tomcat因iText7.1.8未释放.pfm文件崩溃,求解决方案

解决iText7.1.8生成PDF导致Tomcat文件句柄泄漏问题

先直接给结论:是的,使用单例模式复用DefaultFontProvider是解决这个文件句柄泄漏问题的核心方案,下面详细拆解原因和修改方法:

问题根源分析

你的场景里,Tomcat崩溃的直接原因是打开文件句柄数达到系统上限,而这些未释放的文件都是.pfm字体文件——这是因为每次生成PDF时,你都新建了一个DefaultFontProvider(true, true, true)实例。

这个类在初始化时会扫描并加载系统中的字体资源,而iText 7.1.8版本中,频繁创建该实例会导致旧实例持有的字体文件句柄无法被及时回收(JVM垃圾回收不会立刻清理这类底层资源,高并发场景下会快速累积),最终触发Too many open files错误拖垮Tomcat。

为什么单例模式有效

DefaultFontProvider是iText官方设计为线程安全的组件,它的核心职责就是缓存字体资源、避免重复加载。将它做成单例后,整个应用生命周期内只会加载一次字体文件,所有PDF生成请求复用同一个字体提供者,自然不会持续产生新的未释放文件句柄。

修改后的代码示例

你可以把DefaultFontProvider改成静态单例,调整后的代码如下:

public class PdfGenerator {
    // 饿汉式单例:应用启动时初始化一次,全局复用
    private static final DefaultFontProvider GLOBAL_FONT_PROVIDER = new DefaultFontProvider(true, true, true);

    public static File convertToPDF(File pdfFile, URL webURL) {
        InputStream htmlStream = null;
        FileOutputStream pdfStream = null;
        try {
            htmlStream = webURL.openStream();
            pdfStream = new FileOutputStream(pdfFile);
            ConverterProperties properties = new ConverterProperties();
            // 复用全局单例的字体提供者,而非每次新建
            properties.setFontProvider(GLOBAL_FONT_PROVIDER);
            HtmlConverter.convertToPdf(htmlStream, pdfStream, properties);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (htmlStream != null) {
                    htmlStream.close();
                }
                if (pdfStream != null) {
                    pdfStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return pdfFile;
    }
}

额外优化建议

  • 如果担心应用启动时初始化字体影响启动速度,可以改成懒加载单例(比如双重检查锁定方式),不过大部分场景下饿汉式单例的性能表现已经足够。
  • 可以临时调整Ubuntu的文件句柄上限(修改/etc/security/limits.conf)缓解紧急问题,但这只是治标,复用字体提供者才是彻底解决问题的办法。
  • 可以检查iText 7.1.x后续小版本是否修复了字体资源泄漏的已知bug,升级版本也是一个长期优化方向。

内容的提问来源于stack exchange,提问作者Billel Mehdi Bendjaballah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:41:57