Java iText内存管理-PdfReader/水印加载过多

Java iText内存管理-PdfReader/水印加载过多,java,memory-management,itext,watermark,Java,Memory Management,Itext,Watermark,我正在给文档添加水印,我不想把它们完全加载到内存中,因为它们可能相当大。我发现RandomAccessFileOrraray可以缓冲读取,它做得很好,但仍然加载了太多我喜欢的内容 也就是说,在我加载一个5MB的PDF文件后,使用的内存增加了23Mb!当我开始添加水印时,它又跳了27Mb!在那之后,使用过的记忆逐渐增加,但并不可怕 这种行为有什么原因吗?您知道如何定义PdfReader或RandomAccessFileOrArray或其他东西的缓冲区大小吗 谢谢你的意见 printMem方法通过

我正在给文档添加水印,我不想把它们完全加载到内存中,因为它们可能相当大。我发现RandomAccessFileOrraray可以缓冲读取,它做得很好,但仍然加载了太多我喜欢的内容

也就是说,在我加载一个5MB的PDF文件后,使用的内存增加了23Mb!当我开始添加水印时,它又跳了27Mb!在那之后,使用过的记忆逐渐增加,但并不可怕

这种行为有什么原因吗?您知道如何定义PdfReader或RandomAccessFileOrArray或其他东西的缓冲区大小吗

谢谢你的意见


printMem方法通过显示free-used-total来显示内存的状态

这是我的密码

printMem("Before load");
    PdfReader reader = null;
    try {
        reader = new PdfReader(new RandomAccessFileOrArray(new FileInputStream("C:/TEMP/zip/100258.pdf")),null);
        printMem("After load");
        FileOutputStream out = new FileOutputStream(f);
        PdfStamper stamp = new PdfStamper(reader, out);

        int numPages = reader.getNumberOfPages();
        int page=1;
        BaseFont baseFont = 
            BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE,
                BaseFont.WINANSI, BaseFont.EMBEDDED);
        float width;
        float height;

        while (page <= numPages) {
            printMem("Page " + page);
            PdfContentByte cb = stamp.getOverContent(page);
            height = reader.getPageSizeWithRotation(page).getHeight() / 2;
            width = reader.getPageSizeWithRotation(page).getWidth() / 2;

            cb.saveState();
            cb.setColorFill(MEDIUM_GRAY);

            // Primary Text
            cb.beginText();
            cb.setFontAndSize(baseFont, PRIMARY_FONT_SIZE);
            cb.showTextAligned(Element.ALIGN_CENTER, "WatermarkText", width,
                    height, TEXT_TILT_ANGLE);
            cb.endText();

            cb.restoreState();
            page++;
        }
        stamp.close();
    } catch(Throwable e) {
        reader = null;
        System.gc();
    }

如果使用包含文件路径的字符串构造RandomAccessFileOrray(例如new RandomAccessFileOrray(“/path/to/pdf”);则仅部分读取文档。使用InputStream或URL,整个文档将被复制到内部字节数组。

您是否尝试强制垃圾收集以查看它是否真的是内存泄漏,或者是否只是内存未释放?只是关于内存使用情况和pdf大小与页数的注释。内存使用率与文件大小的关系比与页数的关系小。例如:1Mb的一页PDF比10KB的100页PDF需要更少的内存。通过RandomAccessFileOrray进行部分读取,您的代码看起来很好。
Before load | 1566248160 6615840 1572864000
After load | 1542392472 30471528 1572864000
Page 1 | 1515096880 57767120 1572864000
Page 2 | 1515095992 57768008 1572864000
Page 47 | 1512998840 59865160 1572864000
Page 48 | 1512998840 59865160 1572864000