La fusión de 1000 PDF a través de iText lanza java.lang.OutOfMemoryError: espacio de almacenamiento dinámico de Java

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

  •  12-09-2019
  •  | 
  •  

Pregunta

Estoy tratando de combinar archivos PDF 1000 a través de iText. No estoy seguro de que la pérdida de memoria está sucediendo. A continuación se muestra el código de ejemplo. Tenga en cuenta que estoy quitando el archivo secundario-pdf en cuanto me fusiono al archivo principal. Por favor pointout error en el código de abajo o hay alguna forma mejor de hacer esto con un vistazo a la concepción de la memoria. Este proceso se realiza a través de servlet (no programa independiente)

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();
¿Fue útil?

Solución

Es posible que desee probar algo como lo siguiente (manejo de excepciones, archivar y borrar estrecha para mayor claridad):

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

Otros consejos

¿Quién dice que hay una pérdida de memoria? Su documento combinado tiene que caber en la memoria en su totalidad, no hay manera de evitarlo, y bien puede ser mayor que el tamaño de la pila por defecto de 64MB en la memoria (en lugar de en el disco).

No veo un problema con su código, pero si se desea diagnosticar en detalle, montón perfilador uso de VisualVM (viene con el JDK desde Java 6 actualización 10 o así).

¿Qué pasa si no se utiliza de InputStream? Si puede, trate de usar sólo la ruta para que presente el 'nuevo PDFReader ( '/ / archivo somedirectory.').

Esto hace que el lector para actuar en el disco.

El código anterior está tratando de crear un objeto de PdfContentByte (cb) dentro del bucle. Moverlo fuera podría solucionar el problema. He utilizado un código similar en mi solicitud para coser juntos 13k PDF individuales en que un PDF sin problemas.

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

En lugar de la fusión de 1000 PDF, tratar de crear una postal de ellos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top