我一直在使用iText 4.2.1和java 1.6来生成PDF文件。我的任务是使用模板pdf添加两个具有一些随机内容的字段。即使使用1GB大型PDF也能正常工作。但现在环境要求java 7,我遇到了内存不足的问题。 我将iText升级到5.5.3,但问题仍然存在。 代码很简单:
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();
}
}
}
当使用1GB大型pdf文件时,这会产生以下堆栈转储:
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)
这是使用这个基本代码从groovy脚本中调用的:
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."
任何人都知道如何让它发挥作用?
答案 0 :(得分:1)
您可以使用命令行参数来增加Java可用的内存量。以下是我使用的命令行参数的示例 - 您应根据需要和系统内存容量更改数字:
Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote
-XX:PermSize=256m -XX:MaxPermSize=512m
答案 1 :(得分:0)
您可以做的一些选项:
-Xmx
等。请参阅你的JVM文档。)(我想知道为什么iText及其PdfStamper的实现效率不足以在不使用大量内存的情况下完成任务...)
答案 2 :(得分:0)
错误显示“请求的数组大小超过VM限制” - 数组的最大大小约为2GB(Integer.MAX_VALUE)。问题是你在运行什么VM? 32 GB还是64 GB?您可以尝试以下选项(64位VM):
-XX:+ UseCompressedOops