合并1000 PDF到iText会抛出java.lang.OutOfMemoryError:Java堆空间

时间:2009-08-11 14:56:20

标签: java itext out-of-memory

我正在尝试通过iText合并1000个PDF文件。我不确定内存泄漏发生在哪里。下面是示例代码。请注意,我将合并到父文件后立即删除child-pdf文件。请指出以下代码中的错误,或者有没有更好的方法来做内存概念。这个过程是通过servlet(而不是独立程序)完成的

FileInputStream local_fis = null;
BufferedInputStream local_bis = null;
File localFileObj = null;
for(int taIdx=0;taIdx<totalSize;taIdx++){
    frObj = (Form3AReportObject)reportRows.get(taIdx);
    localfilename = companyId + "_" +  frObj.empNumber + ".pdf";

    local_fis = new FileInputStream(localfilename);
    local_bis = new BufferedInputStream(local_fis); 
    pdfReader = new PdfReader(local_bis);

    cb = pdfWriter.getDirectContent(); 
    document.newPage();
    page = pdfWriter.getImportedPage(pdfReader, 1);
    cb.addTemplate(page, 0, 0);
    local_bis.close();
    local_fis.close();

    localFileObj = new File(localfilename);
    localFileObj.delete();
}
document.close();

7 个答案:

答案 0 :(得分:8)

您可能希望尝试以下内容(为了清楚起见,删除了异常处理,文件关闭和删除):

for(int taIdx = 0; taIdx < totalSize; taIdx++) {
    Form3AReportObject frObj = (Form3AReportObject)reportRows.get(taIdx);

    localfilename = companyId + "_" +  frObj.empNumber + ".pdf";

    FileInputStream local_fis = new FileInputStream(localfilename);

    pdfWriter.freeReader(new PdfReader(local_fis));

    pdfWriter.flush();
}

pdfWriter.close();

答案 1 :(得分:2)

谁说有内存泄漏?您的合并文档需要完全适合内存,没有办法解决它,它可能比内存中<64> 的默认堆大小(而不是光盘)大。

我没有看到您的代码存在问题,但是如果您想详细诊断它,use visualvm's heap profiler(自Java 6更新10以来随JDK一起提供)。

答案 2 :(得分:1)

答案 3 :(得分:0)

如果您不使用InputStream怎么办?如果可以,请尝试在'new PDFReader(“/ somedirectory / file。”)上使用您提供的路径。

这使读者可以在磁盘上操作。

答案 4 :(得分:0)

上面的代码试图在循环中创建一个PdfContentByte对象(cb)。将它移到外面可能会解决问题。我在我的应用程序中使用类似的代码将13k个单独的PDF拼接成一个PDF而没有任何问题。

答案 5 :(得分:0)

public class PdfUtils {
     public static void concatFiles(File file1, File file2, File fileOutput) throws Exception {
          List<File> islist =  new ArrayList<File>();
          islist.add(file1);
          islist.add(file2);

          concatFiles(islist, fileOutput);
         }

         public static void concatFiles(List<File> filelist, File fileOutput) throws Exception {
          if (filelist.size() > 0) {
                 PdfReader reader = new PdfReader(new FileInputStream( filelist.get(0)) );
                 Document document = new Document(reader.getPageSizeWithRotation(1));

           PdfCopy cp = new PdfCopy(document,  new FileOutputStream( fileOutput ));

           document.open();


           for (File file : filelist ) {

                PdfReader r = new PdfReader( new FileInputStream( file));
                for (int k = 1; k <= r.getNumberOfPages(); ++k) {
                    cp.addPage(cp.getImportedPage(r, k));
                }
                cp.freeReader(r);

           }
           cp.close();
           document.close();
          } else{             
           throw new Exception("La lista dei pdf da concatenare è vuota");        
          }               
         }
   }

答案 6 :(得分:-1)

不要合并1000个PDF,而是尝试创建它们的拉链。