我的iText有问题。
我正在创建包含大量图像的PDF,因此Java堆空间非常容易用完。
试图用Eclipse Memory Analyzer分析dmp并发现每个图像使用大约10MB的堆空间。但它们在HD上只有大约350KB
是否有机会将堆刷新到HD并继续创建?
还有其他常见的泄漏吗?
不幸的是我找不到任何有用的东西。
这就是一个图像堆的样子
总的来说,我认为添加的元素仍然存在于缓存中...... 我怎么能把它们拿出来?
是否可以使用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();
答案 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中删除章节/章节类。