创建多个PDF后,ITextRenderer.createPDF停止

时间:2014-04-30 12:18:45

标签: pdf-generation playframework-2.1

我遇到了一个问题,我似乎无法解决,我需要你的帮助。

我正在生成一个PDF列表,我写入硬盘驱动器,一切都可以正常处理少量文件,但是当我开始生成更多文件时(通过for循环),创建停止了其他PDF文件没有创建。

我将Play Framework与PDF module一起使用,依赖于ITextRenderer生成PDF。

我通过添加输出以查看它停止的位置来解决问题(好吧,我相信它在这里),问题出在我打电话给.createPDF(os);时。

起初,我只能创建16个文件,然后它会停止,但我创建了一个Singleton,它在Class实例中创建渲染器并重用同一个实例(为了避免添加字体和设置每次)我去了61个文件创建,但没有更多。

我虽然关于内存泄漏阻止了这个过程,但无法查看在哪里或如何正确找到它。

这是我的代码部分:

列出模型; //我从db查询中获得了一个MyModel列表,这个MyModel包含一个文件路径

List<InputStream> files = new ArrayList<InputStream>();

for (MyModel model : models) {
    if (!model.getFile().exists()) {
        model.generatePdf();
    }
    files.add(new FileInputStream(model.getFile()));
}

// generatePDF:

public void generatePdf() {
    byte[] bytes = PDF.toBytes(views.html.invoices.pdf.invoice.render(this, due));


    FileOutputStream output;
    try {
        File file = getFile();
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        output = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(output);
        bos.write(bytes);

        bos.flush();
        bos.close();

        output.flush();
        output.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如您所见,我尽力避免内存泄漏,但这还不够。

为了找到问题,我将PDF.toBytes以及该类中的所有后续调用替换为我的类中的复制/粘贴版本,并添加了输出。这就是我发现线程挂起createPDF,行

的方式

更新1: 我有两个(缩进的)PlayFramework应用程序运行这些参数:

-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m

我试图停止一个实例并重新执行PDF生成,但它并没有影响生成的文件数量,它停在相同数量的文件中。 我还尝试更新分配的记忆:

 -Xms1536m -Xmx1536m -XX:PermSize=1024m -XX:MaxPermSize=1024m

完全没有变化。

有关信息,服务器具有 16 Gb RAM

cat /proc/cpuinfo :

model name  : Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
cpu MHz     : 3101.000
cpu cores   : 4
cache size  : 6144 KB

希望它有所帮助。

2 个答案:

答案 0 :(得分:0)

嗯,我真的很惊讶这个bug与内存,内存泄漏或可用内存完全无关。

我很惊讶。

它与通过网址加载的图像相关,在同一服务器(本地)中加载了很长时间。删除该图像解决了问题。

我将制作一个base64编码的图像,它应该解决问题。

我仍然无法相信!

答案 1 :(得分:0)

该模块由JörgViola开发,我认为假设这方面的一切都很好是安全的。从IText库中,我也相信可以安全地假设一切都是安全的。

正如您所猜测的,瓶颈来自您的代码。有趣的是,不是某些内存没有得到妥善管理,而是来自网络请求,每次都会使PDF渲染变得越来越慢,直到它最终失败。

很高兴你终于让它发挥作用了。