【问题标题】:Apache PDFBOX - getting java.lang.OutOfMemoryError when using split(PDDocument document)Apache PDFBOX - 使用拆分时获取 java.lang.OutOfMemoryError(PDDocument 文档)
【发布时间】:2016-07-04 15:30:07
【问题描述】:

我正在尝试使用 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://stackoverflow.com/questions/37771252/splitting-a-pdf-results-in-very-large-pdf-documents-with-pdfbox-2-0-2 的重复问题:

1.我没有前面提到的尺寸问题 话题。我正在切片一个 270 页的 13.8MB PDF 文件,切片后 每个切片的大小平均为 80KB,总大小为 30.7MB。 2.Split在返回拆分部分之前就抛出异常。

我发现,只要我不传递整个文档,拆分就可以通过,而是将其作为“批次”传递,每个 20-30 页,这样就可以了。

【问题讨论】:

  • 2.0.2 中的已知错误,在修复之前使用 2.0.1。
  • 您是否按照 Tilman 的建议尝试过以前的版本?
  • 我对版本号有限制@GeorgeGarchagudashvili
  • 我没有同样的问题,我没有尺寸问题,也没有随机异常问题。

标签: java pdfbox


【解决方案1】:

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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2021-01-05
    • 2017-03-14
    • 2018-10-03
    • 1970-01-01
    相关资源
    最近更新 更多