دمج 1000 PDF thru itext رميات java.lang.outofmemoryerror: Java Heap Space

StackOverflow https://stackoverflow.com/questions/1260895

  •  12-09-2019
  •  | 
  •  

سؤال

أحاول دمج 1000 ملفات PDF من خلال itext. لست متأكدا من أن تسرب الذاكرة يحدث. أدناه هو نموذج التعليمات البرمجية. لاحظ أنني أزيل ملف الطفل 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();
هل كانت مفيدة؟

المحلول

قد ترغب في تجربة شيء مثل ما يلي (معالجة الاستثناءات، ملف إغلاق وحذف إزالته من أجل الوضوح):

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

نصائح أخرى

من يقول أن هناك تسرب الذاكرة؟ تحتاج وثيقتك المدمجة إلى تنسيق الذاكرة في مجملها، ولا توجد وسيلة حولها، وقد تكون أكبر من حجم الكومة الافتراضي 64 ميغابايت في الذاكرة (بدلا من القرص).

لا أرى مشكلة في التعليمات البرمجية الخاصة بك، ولكن إذا كنت ترغب في تشخيصه بالتفصيل، استخدم PhoryVM's Heap Profiler (يأتي مع JDK منذ تحديث Java 6 10 أو نحو ذلك).

هل حاولت زيادة حجم كومة الكومة الأقصى من الافتراضي (الذي هو 64 ميجابايت فقط)؟

يرى:

ماذا لو كنت لا تستخدم inputstream؟ إذا كنت تستطيع، فحاول استخدام المسار فقط لملفك على "PDFRIDERER جديد (" / ملف / ملف أحمق. ").

هذا جعل القارئ للعمل على القرص.

الرمز أعلاه يحاول إنشاء PdfContentByte هدف (cb) داخل الحلقة. نقله خارج قد يحل المشكلة. لقد استخدمت رمز مماثل في طلبي على غرزة معا PDF الفردية 13K في ملف PDF واحد دون مشكلة.

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

بدلا من دمج 1000 ملفات PDF، حاول إنشاء مضغوط منهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top