当前位置: 首页 > 面试题库 >

Apache PDFBOX-使用split(PDDocument文档)时出现java.lang.OutOfMemoryError

酆英达
2023-03-14
问题内容

我正在尝试使用Apache PDFBOX API V2.0.2拆分300页的文档。尝试使用以下代码将pdf文件拆分为单个页面时:

        PDDocument document = PDDocument.load(inputFile);
        Splitter splitter = new Splitter();
        List<PDDocument> splittedDocuments = splitter.split(document); //Exception happens here

我收到以下异常

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

这表明GC需要花费大量时间来清除没有被回收量证明合理的堆。

有许多JVM调优方法可以解决这种情况,但是,所有这些方法都只是在解决症状而不是真正的问题。

最后一点,我正在使用JDK6,因此在我的情况下,不能使用新的Java 8 Consumer。

编辑:

这不是http://codingdict.com/questions/159530的重复问题,如下所示:

 1.我没有上述提到的尺寸问题
    话题。我将270页的13.8MB切片,然后切片
    每个切片的大小平均为80KB,总大小为
    30.7兆字节
 2.即使在拆分之前,拆分也会引发异常。

我发现只要不传递整个文档,拆分就可以通过,而是将其作为“批量”传递,每个批量20-30页,即可完成工作。


问题答案:

PDF
Box将拆分操作产生的零件作为PDDocument类型的对象存储为堆中的对象,这会导致堆快速填充,即使在循环的每一轮之后调用close()操作,GC仍会无法以与填充相同的方式回收堆大小。

一种选择是将文档拆分操作拆分为多个批次,其中每个批次是一个相对易于管理的块(10至40页)

public void execute() {
    File inputFile = new File(path/to/the/file.pdf);
    PDDocument document = null;
    try {
        document = PDDocument.load(inputFile);

        int start = 1;
        int end = 1;
        int batchSize = 50;
        int finalBatchSize = document.getNumberOfPages() % batchSize;
        int noOfBatches = document.getNumberOfPages() / batchSize;
        for (int i = 1; i <= noOfBatches; i++) {
            start = end;
            end = start + batchSize;
            System.out.println("Batch: " + i + " start: " + start + " end: " + end);
            split(document, start, end);
        }
        // handling the remaining
        start = end;
        end += finalBatchSize;
        System.out.println("Final Batch  start: " + start + " end: " + end);
        split(document, start, end);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //close the document
    }
}

private void split(PDDocument document, int start, int end) throws IOException {
    List<File> fileList = new ArrayList<File>();
    Splitter splitter = new Splitter();
    splitter.setStartPage(start);
    splitter.setEndPage(end);
    List<PDDocument> splittedDocuments = splitter.split(document);
    String outputPath = Config.INSTANCE.getProperty("outputPath");
    PDFTextStripper stripper = new PDFTextStripper();

    for (int index = 0; index < splittedDocuments.size(); index++) {
        String pdfFullPath = document.getDocumentInformation().getTitle() + index + start+ ".pdf";
        PDDocument splittedDocument = splittedDocuments.get(index);

        splittedDocument.save(pdfFullPath);
    }
}


 类似资料:
  • 我正在尝试使用Apache PDFBOX API V2.0.2拆分一个有300页的文档。同时尝试使用以下代码将pdf文件拆分为单页: 我收到以下异常 这表明GC花费了很多时间来清除回收量不合理的堆。 有很多JVM调优方法可以解决这种情况,但是,所有这些都只是治疗症状,而不是真正的问题。 编辑: 这不是http://stackoverflow.com/questions/37771252/split

  • 我已经用iText创建了一个文档,我想把这个文档(保存为PDF文件)转换成一个图像。为此,我使用PDFBox,它需要一个PDDocument作为输入。我使用以下代码: 此时,我从已保存的文件中加载文档。但我希望在Java内部执行此操作。 所以我的问题是:如何将文档转换为PDDocument? 非常感谢任何帮助!

  • 问题内容: 在这种情况下,我在textarea中设置文本期间发现以下错误。我不知道该怎么解决。 我认为问题是在文档中设置文本或在文档侦听器中设置文档。但是我不知道该怎么解决。请帮我解决这个问题。 问题答案: 您不能在DocumentListener中修改文档。而是编写一个自定义Document,该文档将覆盖insertString()或remove()方法。 来自Java教程:如何编写Docume

  • 我正在熟悉PDFBOX的口味。我想知道是否有一种方法可以将pdf-layout元素放入PDDocument对象中。pdf-layout元素使用Document作为父元素,PDFBox使用PDDocument作为父元素。 使用的库:https://pdfbox.apache.org/2.0/examples.html和https://github.com/ralfstuckert/pdfbox-la

  • 我正在尝试使用他们网站上提供的Docx4j社区包将一个Word文件转换成PDF。(http://www . docx 4 Java . org/docx 4j/docx 4j-community-3 . 3 . 1 . zip) 看起来这个包上的docx4j和FOP之间存在版本不兼容问题,我想知道以前是否有人遇到过这个问题,您是否知道什么版本的库可以实现这个功能。 这是我的代码: 我复制了下面的s

  • 当我使用PDDocument和PDFTextStripper方法时,尽管导入了所有必需的库,但我还是收到了错误。