在创建PDF时减少Java堆空间消耗

时间:2012-09-06 10:32:46

标签: java memory memory-leaks itext

我的iText有问题。

我正在创建包含大量图像的PDF,因此Java堆空间非常容易用完。

试图用Eclipse Memory Analyzer分析dmp并发现每个图像使用大约10MB的堆空间。但它们在HD上只有大约350KB

是否有机会将堆刷新到HD并继续创建?

还有其他常见的泄漏吗?

不幸的是我找不到任何有用的东西。

Heap

这就是一个图像堆的样子

总的来说,我认为添加的元素仍然存在于缓存中...... 我怎么能把它们拿出来?

是否可以使用this

这是我当时使用的代码:

Document document = new Document();
PdfWriter writer = null;
        try {
            writer = PdfWriter.getInstance(document, new FileOutputStream(this.savePath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

document.open();

Paragraph pdfTitle = new Paragraph();
pdfTitle.add(new Phrase("Title"));

try {
    document.add(pdfTitle);
    document.add(Chunk.NEWLINE);

} catch (DocumentException e) {
    e.printStackTrace();
}

for(int x = 0; x < 10; x++){
    //chapter
    Paragraph chapterName = new Paragraph("Chapter "+x, FONT[1]);
    ChapterAutoNumber chapter = new ChapterAutoNumber(chapterName);

    try {
    document.add(chapterhapter);
    } catch (DocumentException e) {
        e.printStackTrace();
    }

    for(int y = 0; y < 10; y++){
        //sec
        Paragraph sectionName = new Paragraph("Section "+y, FONT[2]);

        Section section  = chapter.addSection(sectionName);

        for(int z = 0; z < 10; z++){
            //subSec
            Section subSection = null;

            Image image = null;
            try {
            image = Image.getInstance(path);
            } catch (BadElementException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            image.scalePercent(50);

            image.setCompressionLevel(9);
            Paragraph subDesc = new Paragraph("Desc "+z, FONT[3]);

            subSection = section.addSection(subDesc);

            picSection.add(image);

            try {
                document.add(subSection);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

        }

    }

}

document.close();

3 个答案:

答案 0 :(得分:1)

这里有一些有用的答案:Java heap space out of memory

尝试将图像附加到PDF后将其设置为null?

答案 1 :(得分:1)

我的第一个猜测是搜索iText文档以获得某种流媒体支持。有没有办法不存储在内存中创建的整个PDF? RTFM。

第二个选项当然是为了增加应用程序的堆大小,如果你有适当的硬件。

而且,为了以防万一,我应该提一下内存泄漏的可能性。虽然在您的情况下看起来似乎不太可能,但如果您需要它,可以Plumbr:)

答案 2 :(得分:1)

我是iText的原始开发人员,因为您的代码完全错误,我对您的问题进行了低估。

例如:您创建了一个章节对象,但您并未将其添加到文档中。相反,你要添加一个未在任何地方定义的picSection对象。

然而,我的主要批评是,您正在使用实现LargeElement接口的ChapterAutoNumber对象,并抱怨内存使用。这就像是说:我每天都吃一罐mayonaise,我想知道:为什么我这么胖?

为什么使用章节?如果书签是选择这些对象的主要原因,那么如果要减少使用的内存,则应切换到使用PdfOutline。因为现在,您通过将它们添加到Chapter对象来构建大量对象,并且只有在将章添加到文档时才能释放这些对象。在那之前,进行垃圾收集是没有用的,因为垃圾收集器不能丢弃存储在Chapter对象中的内容。

如果您沉迷于使用Chapter类,请查看setComplete()方法,并定期将该章的一小部分添加到文档中,以便可以一点一点地释放对象。第一种方法(不使用章节类)远比第二种方法好。

如果我看到更多这样的问题,我可能决定从iText中删除章节/章节类。