2014-10-08 6 views
2

iText 4.2.1 및 Java 1.6을 사용하여 PDF 파일을 생성했습니다. 내 임무는 템플릿 pdf를 사용하여 임의의 내용을 갖는 두 개의 필드를 추가하는 것입니다. 1GB 크기의 큰 PDF로도 잘 작동합니다. 하지만 이제 환경은 자바 7을 요구하고 나는 메모리 부족 문제를 겪는다. iText를 5.5.3으로 업그레이드했지만 여전히 동일한 문제입니다. 코드는 간단하다 :iText 사용 : java.lang.OutOfMemoryError : 요청한 배열 크기가 VM 한도를 초과합니다.

1GB의 큰 PDF 파일을 사용할 때 다음과 같은 스택 덤프를 제공
public final class PdfHelper 
{ 
    public static void randomizePDFStream(InputStream in, OutputStream out) 
    { 
     try 
     { 
      PdfReader ReadInputPDF; 
      ReadInputPDF = new PdfReader(in); 
-> crash   PdfStamper stamper = new PdfStamper(ReadInputPDF, out); 
      HashMap<String, String> hMap = ReadInputPDF.getInfo(); 
      hMap.put("Title", "RANDOM PDF TITLE: " + System.nanoTime() + ", " + System.currentTimeMillis()); 
      hMap.put("Subject", "RANDOM PDF SUBJECT: " + System.currentTimeMillis() + ", " + System.nanoTime()); 
      stamper.setMoreInfo(hMap); 
      stamper.close(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

:

mPDFFiles[i] = new java.io.File(getTempDirectory(), String.format("temp_file_%s_%s.pdf", System.nanoTime(), i)); 
mPDFFiles[i].createNewFile(); 

input = new BufferedInputStream(new FileInputStream(mTemplateFiles[i])); 
output = new BufferedOutputStream(new FileOutputStream(mPDFFiles[i])); 

long start=System.currentTimeMillis(); 
PdfHelper.randomizePDFStream(input, output); 
output.flush(); 
println "Conversion time: " + (System.currentTimeMillis()-start) + " ms." 
이이 기본 코드와 그루비 스크립트에서 호출

Caught: java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
     at java_util_concurrent_Future$get.call(Unknown Source) 
     at Main.awaitCompletion(Main.groovy:222) 
     at Main$awaitCompletion.callCurrent(Unknown Source) 
     at Main.run(Main.groovy:113) 
Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
     at com.itextpdf.text.io.StreamUtil.inputStreamToArray(StreamUtil.java:74) 
     at com.itextpdf.text.io.RandomAccessSourceFactory.createSource(RandomAccessSourceFactory.java:146) 
     at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:351) 
     at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:371) 
     at PdfHelper.randomizePDFStream(PdfHelper.java:65) 

어떻게 작동시키는 지 알고있는 사람이 있습니까?

+0

당신이 JVM 힙 크기를 증가 시도? http://viralpatel.net/blogs/jvm-java-increase-heap-size-setting-heap-size-jvm-heap/ – Leo

+0

글쎄, 당연히 나는 Xmx와 MaxHeapSize를 상당히 증가 시키려고 노력했지만, 여전히 같은 문제. 현재 -Xms = 8192m -Xmx16g -XX : MaxPermSize = 8192m로 실행 중입니다. 그리고 제가 언급했듯이, jdk1.6을 사용하면 모든 것이 잘 돌아갑니다. –

+0

'PdfStamper stamper = 새로운 PdfStamper (ReadInputPDF, out, true);'추가 모드에서. 그러나 나는 의심한다. 특정 데이터 오류가있는 것 같습니다. 다른 PDF를 시도해보고 PDF를 임시 파일에 쓰고 새 임시 PDF를 사용하십시오. –

답변

1

명령 줄 매개 변수를 사용하여 Java에서 사용할 수있는 메모리 양을 늘릴 수 있습니다. 여기 내가 사용하는 명령 줄 매개 변수의 예입니다 - 당신이 당신의 요구와 시스템 메모리 용량을 적절하게 번호를 변경해야합니다 : 당신이 무엇을 할 수 있는지의

Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote 
-XX:PermSize=256m -XX:MaxPermSize=512m 
0

일부 옵션 :

  1. 더 많은 메모리 (예 : -Xmx 등)를 사용할 수 있도록 JVM (Groovy 코드와 PdfStamper를 실행 함)에 JVM 문서를 문의하십시오.
  2. 전체 PDF를 메모리에로드 할 필요가없는 구현을 찾으십시오 (적어도 한 번에). 합니다 (iText를 구현하고 PdfStamper가 대량의 메모리를 사용하지 않고 작업을 수행 할만큼 효율적이지 왜 내가 궁금하네요 ...)

1

이 오류는 "요청 배열 크기를 초과 말한다 VM limit "- 배열의 최대 크기는 약 2GB입니다 (Integer.MAX_VALUE). 질문은 VM을 실행 중인지 여부입니다. 32GB 또는 64GB? 다음 옵션 (64 비트 VM)을 시도 할 수 있습니다 :

-XX

: + UseCompressedOops

관련 문제