PDFBOX java.lang.OutOfMemoryError:java堆空间;超出了GC开销限制

时间:2015-09-28 14:00:27

标签: java garbage-collection out-of-memory pdfbox

我正在开发一个Java项目。 我从服务器检索pdf并将其转换为图像,以将像素与预期文件进行比较。 当我只用20-30个文件运行它时程序很好,但是当我尝试使用超过30个文件时,它会抛出OutOfMemoryError。

好像是pdf - >图像转换方法正在产生OutOfMemoryError。

以下是方法:

    PDDocument document = null;
    try {
        document = PDDocument.loadNonSeq(new File(pdfFile), null);
        List<PDPage> pages = new ArrayList<PDPage>();
        for (Object obj : document.getDocumentCatalog().getAllPages()) {
            PDPage page = (PDPage) (obj);
            pages.add(page);
        }
        int pageNum = 0;
        for (PDPage pdPage : pages) {
            BufferedImage img = pdPage.convertToImage(BufferedImage.TYPE_INT_RGB, 100);
            if (isExpected) {
                ImageIOUtil.writeImage(img, FolderUtils.getImageFolder(websiteName) + File.separator + "expected"
                        + (++pageNum) + ".png", 100);
            } else {
                ImageIOUtil.writeImage(img, FolderUtils.getImageFolder(websiteName) + File.separator + "rendered"
                        + (++pageNum) + ".png", 100);
            }
            img.flush();
            img = null;
        }
    } catch (IOException e) {
        debugLog.log(Level.SEVERE, e.getMessage(), e);
    } finally {
        if (document != null) {
            try {
                document.close();
                document = null;
            } catch (IOException e) {
                debugLog.log(Level.SEVERE, e.getMessage(), e);
            }
        }
    }

这是Java堆空间日志的一部分:

Exception in thread "pool-1-thread-1" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
    at java.awt.image.Raster.createPackedRaster(Raster.java:467)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
    at java.awt.image.BufferedImage.<init>(BufferedImage.java:340)
    at org.apache.pdfbox.pdmodel.graphics.xobject.CompositeImage.createMaskedImage(CompositeImage.java:85)
    at org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage.applyMasks(PDXObjectImage.java:158)
    at org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap.getRGBImage(PDPixelMap.java:367)
    at org.apache.pdfbox.util.operator.pagedrawer.Invoke.process(Invoke.java:87)
    at org.apache.pdfbox.util.PDFStreamEngine.processOperator(PDFStreamEngine.java:557)
    at org.apache.pdfbox.util.PDFStreamEngine.processSubStream(PDFStreamEngine.java:268)
    at org.apache.pdfbox.util.PDFStreamEngine.processSubStream(PDFStreamEngine.java:235)
    at org.apache.pdfbox.util.PDFStreamEngine.processStream(PDFStreamEngine.java:215)
    at org.apache.pdfbox.pdfviewer.PageDrawer.drawPage(PageDrawer.java:139)
    at org.apache.pdfbox.pdmodel.PDPage.convertToImage(PDPage.java:801)
    at ********************.convertPDFToImages(Processor.java:107)
    at ********************.APIProcessor.run(APIProcessor.java:62)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

以下是GC开销限制的日志部分超出:

Exception in thread "pool-1-thread-3" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.Collections.singletonList(Collections.java:3349)
    at org.apache.pdfbox.pdfparser.NonSequentialPDFParser.parseDictObjects(NonSequentialPDFParser.java:1275)
    at org.apache.pdfbox.pdfparser.NonSequentialPDFParser.initialParse(NonSequentialPDFParser.java:414)
    at org.apache.pdfbox.pdfparser.NonSequentialPDFParser.parse(NonSequentialPDFParser.java:886)
    at org.apache.pdfbox.pdmodel.PDDocument.loadNonSeq(PDDocument.java:1273)
    at org.apache.pdfbox.pdmodel.PDDocument.loadNonSeq(PDDocument.java:1256)
    at *********************.convertPDFToImages(Processor.java:99)
    at ********************.APIProcessor.run(APIProcessor.java:62)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

此外,第一个Java堆空间错误发生在id22,第二个错误发生在id33。 我在MAVEN_OPTS=-d64 -Xms500M -Xmx7000M -XX:PermSize=65M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Temp\heapDump.txt -Xdebug -Xrunjdwp:transport=dt_socket,address=8123,server=y,suspend=n

的服务器上使用8GB RAM

我可以请求帮助解决我的代码有什么问题吗?或者是什么原因引起了这个问题?有内存泄漏吗?

P.S。:以下是渲染的pdf文件和JConsole屏幕截图的链接: https://www.dropbox.com/sh/86gxnmnk5gl66k6/AAAFE_lapBr3cH8EMlXu94qJa?dl=0

另外,我现在在8GB RAM服务器上运行该程序。但如果我在本地16GB RAM笔记本电脑上运行它,就没有java堆空间错误。

1 个答案:

答案 0 :(得分:-1)

我们确实在PDFBox图像转换方面遇到了一些问题。它通过缓冲图像消耗了大量的堆空间,并且是一个定时炸弹,因为它增加了生成页面的数量。

我们的解决方案是改变库。我们确实用JPedal获得了良好的性能,如果事情没有改变,他们确实有他们框架的LGPL版本。