使用 PDFBox Annotation constructAppearances() 方法获取 OutOfMemoryError
Getting OutOfMemoryError with PDFBox Annotation constructAppearances() method
一言以蔽之
我一直在开发一个获取 pdf 的程序,突出显示一些单词(通过 pdfbox 标记注释)并保存新的 pdf。
为了让这些注释在某些查看器(如 pdf.js 上可见),需要在将标记注释添加到页面注释列表之前调用 pdAnnotationTextMarkup.constructAppearances()。
但是,通过这样做,我在处理包含数千个标记注释的大型文档时遇到了 OutOfMemoryError。
我想知道是否有办法防止这种情况发生。
(这是 的 sequel 的一种,但与此关系不大)
技术规格:
PDFBox 2.0.17
Java 11.0.6+10,采用OpenJDK
MacOS Catalina 10.15.2, 16gb, x86_64
我的代码
//my pdf has 216 pages
for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) {
PDPage page = document.getPage(pageIndex);
List<PDAnnotation> annotations = page.getAnnotations();
// each coordinate obj represents a hl annotation. crashing with 7.816 elements
for (CoordinatePoint coordinate : coordinates) {
PDAnnotationTextMarkup txtMark = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
txtMark.setRectangle(pdRectangle);
txtMark.setQuadPoints(quadPoints);
txtMark.setColor(getColor());
txtMark.setTitlePopup(coordinate.getHintDescription());
txtMark.setReadOnly(true);
// this is what makes everything visible on pdf.js and what causes the Java heap space error
txtMark.constructAppearances();
annotations.add(txtMark);
}
}
当前结果
这是导致问题的大量 pdf 文档:
https://pdfhost.io/v/I~nu~.6G_French_Intensive_Care_Society_International_congress_Ranimation_2016.pdf
我的程序试图在整个 216 页中添加 7.816 注释。
和堆栈跟踪:
[main] INFO highlight.PDFAnnotation - Highlighting 13613_2016_Article_114.pdf...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.pdfbox.io.ScratchFile.<init>(ScratchFile.java:128)
at org.apache.pdfbox.io.ScratchFile.getMainMemoryOnlyInstance(ScratchFile.java:143)
at org.apache.pdfbox.cos.COSStream.<init>(COSStream.java:61)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDAbstractAppearanceHandler.createCOSStream(PDAbstractAppearanceHandler.java:106)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateNormalAppearance(PDHighlightAppearanceHandler.java:136)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateAppearanceStreams(PDHighlightAppearanceHandler.java:59)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:175)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:147)
at highlight.PDFAnnotation.drawHLAnnotations(PDFAnnotation.java:288)
我已经尝试将我的 jvm xmx 和 xms 参数增加到 -Xmx10g -Xms10g
,这只是稍微推迟了崩溃。
我想要什么
我想避免这个内存问题,并且仍然能够在 pdf.js 查看器中看到我的注释。不调用 constructAppearances 过程要快得多,我没有这个问题,但是注释只能在某些 pdf 查看器上看到,比如 Adobe。
有什么建议吗?我是不是做错了什么或者遗漏了什么?
在即将发布的2.0.19版本中,构建外观如下:
annotation.constructAppearances(document);
在 2.0.18 及更早版本中,您需要自己初始化外观处理程序:
setCustomAppearanceHandler(new PDHighlightAppearanceHandler(annotation, document));
该行可以在 2.0.19 中删除,因为这是默认的外观处理程序。
为什么会这样?因此,文档公共内存 space ("scratch file") 用于注释处理程序,而不是每次都创建一个新的(这很大)。后者是在调用 new COSStream()
而不是 document.getDocument().createCOSStream()
时完成的。
所有这些当然只有在做很多注释时才重要。
相关 PDFBox 问题:PDFBOX-4772 and PDFBOX-4080
一言以蔽之
我一直在开发一个获取 pdf 的程序,突出显示一些单词(通过 pdfbox 标记注释)并保存新的 pdf。
为了让这些注释在某些查看器(如 pdf.js 上可见),需要在将标记注释添加到页面注释列表之前调用 pdAnnotationTextMarkup.constructAppearances()。
但是,通过这样做,我在处理包含数千个标记注释的大型文档时遇到了 OutOfMemoryError。
我想知道是否有办法防止这种情况发生。
(这是
技术规格:
PDFBox 2.0.17
Java 11.0.6+10,采用OpenJDK
MacOS Catalina 10.15.2, 16gb, x86_64
我的代码
//my pdf has 216 pages
for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) {
PDPage page = document.getPage(pageIndex);
List<PDAnnotation> annotations = page.getAnnotations();
// each coordinate obj represents a hl annotation. crashing with 7.816 elements
for (CoordinatePoint coordinate : coordinates) {
PDAnnotationTextMarkup txtMark = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
txtMark.setRectangle(pdRectangle);
txtMark.setQuadPoints(quadPoints);
txtMark.setColor(getColor());
txtMark.setTitlePopup(coordinate.getHintDescription());
txtMark.setReadOnly(true);
// this is what makes everything visible on pdf.js and what causes the Java heap space error
txtMark.constructAppearances();
annotations.add(txtMark);
}
}
当前结果
这是导致问题的大量 pdf 文档: https://pdfhost.io/v/I~nu~.6G_French_Intensive_Care_Society_International_congress_Ranimation_2016.pdf
我的程序试图在整个 216 页中添加 7.816 注释。
和堆栈跟踪:
[main] INFO highlight.PDFAnnotation - Highlighting 13613_2016_Article_114.pdf...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.pdfbox.io.ScratchFile.<init>(ScratchFile.java:128)
at org.apache.pdfbox.io.ScratchFile.getMainMemoryOnlyInstance(ScratchFile.java:143)
at org.apache.pdfbox.cos.COSStream.<init>(COSStream.java:61)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDAbstractAppearanceHandler.createCOSStream(PDAbstractAppearanceHandler.java:106)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateNormalAppearance(PDHighlightAppearanceHandler.java:136)
at org.apache.pdfbox.pdmodel.interactive.annotation.handlers.PDHighlightAppearanceHandler.generateAppearanceStreams(PDHighlightAppearanceHandler.java:59)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:175)
at org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup.constructAppearances(PDAnnotationTextMarkup.java:147)
at highlight.PDFAnnotation.drawHLAnnotations(PDFAnnotation.java:288)
我已经尝试将我的 jvm xmx 和 xms 参数增加到 -Xmx10g -Xms10g
,这只是稍微推迟了崩溃。
我想要什么
我想避免这个内存问题,并且仍然能够在 pdf.js 查看器中看到我的注释。不调用 constructAppearances 过程要快得多,我没有这个问题,但是注释只能在某些 pdf 查看器上看到,比如 Adobe。
有什么建议吗?我是不是做错了什么或者遗漏了什么?
在即将发布的2.0.19版本中,构建外观如下:
annotation.constructAppearances(document);
在 2.0.18 及更早版本中,您需要自己初始化外观处理程序:
setCustomAppearanceHandler(new PDHighlightAppearanceHandler(annotation, document));
该行可以在 2.0.19 中删除,因为这是默认的外观处理程序。
为什么会这样?因此,文档公共内存 space ("scratch file") 用于注释处理程序,而不是每次都创建一个新的(这很大)。后者是在调用 new COSStream()
而不是 document.getDocument().createCOSStream()
时完成的。
所有这些当然只有在做很多注释时才重要。
相关 PDFBox 问题:PDFBOX-4772 and PDFBOX-4080