1000 PDF à travers la fusion iText jette java.lang.OutOfMemoryError: espace de tas Java

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

  •  12-09-2019
  •  | 
  •  

Question

Je suis en train de fusionner 1000 fichiers PDF à travers iText. Je ne sais pas où la fuite de mémoire se produit. Ci-dessous l'exemple de code. Notez que je retire le fichier pdf enfant dès que je fusionner le fichier parent. S'il vous plaît POINTOUT bug dans le code ci-dessous ou est-il une meilleure façon de le faire avec la conception en mémoire. Ce processus se fait à travers servlet (non programme autonome)

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();
Était-ce utile?

La solution

Vous pouvez essayer quelque chose comme ce qui suit (gestion des exceptions, fichier fermer et supprimer pour plus de clarté):

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

Autres conseils

Qui a dit il y a une fuite de mémoire? Votre besoin document fusionné pour entrer dans la mémoire dans son intégralité, il n'y a rien autour de lui, et il peut bien être plus grande que la taille du segment par défaut de 64MB dans la mémoire (plutôt que sur le disque).

Je ne vois pas de problème avec votre code, mais si vous voulez diagnostiquer en détail, profileur tas d'utilisation visualvm (livré avec le JDK depuis Java 6 update 10 environ).

Que faire si vous n'utilisez pas InputStream? Si vous le pouvez, essayez d'utiliser tout le chemin pour vous déposer sur « nouvelle PDFReader ( « / unrépertoire / fichier. »).

faire le lecteur à agir sur le disque.

Le code ci-dessus tente de créer un objet PdfContentByte (de cb) dans la boucle. Déplacer à l'extérieur pourrait résoudre le problème. Je code similaire dans mon application pour assembler 13k PDF individuels à un PDF sans problème.

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

Au lieu de fusionner 1000 fichiers PDF, essayez de créer un zip d'entre eux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top