Itext를 통해 1000 PDF 병합 java.lang.outofMemoryError : Java Heap Space
-
12-09-2019 - |
문제
ITEXT를 통해 1000 PDF 파일을 병합하려고합니다. 메모리 누출이 어디에서 발생하는지 잘 모르겠습니다. 아래는 샘플 코드입니다. 부모 파일과 합병하자마자 child-pdf 파일을 제거하고 있습니다. 아래 코드의 버그를 가리키거나 메모리 개념으로이를 수행하는 더 좋은 방법이 있습니까? 이 프로세스는 서블릿을 통해 수행됩니다 (독립형 프로그램 아님)
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();
다른 팁
누가 메모리 누출이 있다고 말합니까? 합병 된 문서는 전체적으로 메모리에 맞아야하며 주변에 방법이 없으며 기본 힙 크기 64MB보다 클 수 있습니다. 메모리에서 (디스크 대신).
코드에 문제가 없지만 자세히 진단하려면, VisualVM의 힙 프로파일 러를 사용하십시오 (Java 6 업데이트 10 정도 이후 JDK와 함께 제공됩니다).
기본값에서 최대 힙 크기를 늘리셨습니까 (64MB에 불과)?
보다:
InputStream을 사용하지 않으면 어떻게됩니까? 가능하다면 '새 PDFREADER ( "/SEMEDIRECTORY/FILE.")에 파일을위한 경로 만 사용해보십시오.
이것은 독자가 디스크에서 행동하게 만듭니다.
위의 코드는 a를 만들려고합니다 PdfContentByte
물체 (cb
) 루프 내에서. 밖으로 옮기면 문제가 해결 될 수 있습니다. 나는 응용 프로그램에서 유사한 코드를 사용하여 13k 개별 PDF를 하나의 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를 병합하는 대신 지퍼를 만들어보십시오.