Reputation: 31
I'vew been using iText 4.2.1 and java 1.6 to generate PDF-files. My task is to add two fields having some random content using a template pdf. It works fine even with an 1GB large PDF. But now the environment demands java 7 and I run into this Out of memory-problem. I'v upgraded the iText to 5.5.3, but still the same issue. The code is trivial:
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();
}
}
}
This gives the following stack dump when using a 1GB large pdf file :
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)
This is called from a groovy script with this basic code:
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."
Anyone having an idea how to get this to work?
Upvotes: 3
Views: 10748
Reputation: 162
Some options of what you could do:
-Xmx
etc. Consult your JVM documentation).(I'm wondering why the implementation of iText and its PdfStamper is not efficient enough to accomplish your task without using a huge amount of memory...)
Upvotes: 0
Reputation: 9816
The error says "Requested array size exceeds VM limit" - the maximum size of an array is around 2GB (Integer.MAX_VALUE). The question is what VM are you running? 32 GB or 64 GB? You may try the following options (64 Bit VM):
-XX:+UseCompressedOops
Upvotes: 0
Reputation: 3005
You can use command-line parameters to increase the amount of memory available to Java. Here is an example of the command-line parameters that I use - you should change the numbers as appropriate for your needs and system memory capacity:
Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote
-XX:PermSize=256m -XX:MaxPermSize=512m
Upvotes: 1