我已使用以下命令从命令行启动jar
java -Xms1200m -Xmx1500m -jar xxx.jar
我正在创建BufferedImage
,其大小为12600 * 12600表示需要
606 MB 的内存
TranscoderInput input = new TranscoderInput(sr);
String pngFile = "Style-" + shoeViewer.getCurrentStyle() + "_"
+ shoeViewer.getSelectedMetadata().getSizeLabel()
+ "_400DPI" + ".png";
File outputFile = new File(pngFile);
FileOutputStream fo = new FileOutputStream(outputFile);
TranscoderOutput output = new TranscoderOutput(fo);
long now = System.currentTimeMillis();
t.transcode(input, null);
当我在执行上面的行之前调试内存使用情况时,我的运行时显示
我需要606 MB的内存, 1100 MB仍然是免费的。
因此,当我在34分钟后运行上面的代码时,它会抛出OutOfMemory
例外。
有什么问题?是处理问题还是堆问题?为什么需要34分钟?
我的电脑配置如下
Windows 32bit XP Service Pack2 Home Edition
Amd Athlon (tm) 7750 Dual Core 2.71 GHz
2GB of DDR2 RAM
java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) Client VM (build 23.7-b01, mixed mode, sharing)
请帮助我解决这个问题。
下面的是带有调试消息的异常堆栈。
在运行上面的代码之前,我将VM参数更改为以下
java -Xms900m -Xmx1024m -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=70 -jar myjar.jar
从SVG Reader构建XML文档.... 从SVG Reader构建完成的XML文档.... 将修改后的XML文档转换为String Writer .... 将修改后的XML文档转换为String Writer .... claimBytes 766 Avaialbel Bytes 900189232 内存统计------------------------ 总内存为字节:912326656总内存为兆字节:870 已用内存为字节:9308384已用内存为兆字节:8 Freememory是字节:900189096可用内存是兆字节:858
转码开始于:2013年3月24日星期日11:09:59
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa
ce
at java.awt.image.DataBufferInt.<init>(Unknown Source)
at java.awt.image.SinglePixelPackedSampleModel.createDataBuffer(Unknown
Source)
at java.awt.image.Raster.createWritableRaster(Unknown Source)
at org.apache.batik.gvt.renderer.StaticRenderer.updateWorkingBuffers(Sta
ticRenderer.java:536)
at org.apache.batik.gvt.renderer.StaticRenderer.repaint(StaticRenderer.j
ava:375)
at org.apache.batik.gvt.renderer.StaticRenderer.repaint(StaticRenderer.j
ava:344)
at org.apache.batik.transcoder.image.ImageTranscoder.transcode(ImageTran
scoder.java:111)
at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstra
ctTranscoder.java:142)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstra
ctTranscoder.java:156)
at com.mmg.app.eventlistener.PlaceOrderActionListener.save(PlaceOrderAct
ionListener.java:302)
at com.mmg.app.eventlistener.PlaceOrderActionListener.saveCanvas(PlaceOr
derActionListener.java:270)
at com.mmg.app.eventlistener.PlaceOrderActionListener.actionPerformed(Pl
aceOrderActionListener.java:143)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
ce)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
答案 0 :(得分:2)
即使原始的未编码图像只能填充大约600 MB,编码器中的内部表示可能需要更多内存,具体取决于它的实现方式。以下示例显示将简单svg文件缩放到12600 x 12600(32位)时使用的内存量。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
public class Test {
public static void main(String[] args) throws Exception {
PNGTranscoder t = new PNGTranscoder();
t.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(12600));
t.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(12600));
FileInputStream fis = new FileInputStream("C:\\StackOverflow\\SVG-logo.svg");
TranscoderInput input = new TranscoderInput(fis);
OutputStream ostream = new FileOutputStream("C:\\StackOverflow\\res.png");
TranscoderOutput output = new TranscoderOutput(ostream);
System.out.println("AllocatedMemory: \t" + (Runtime.getRuntime().totalMemory() / 1024) + " Kb");
t.transcode(input, output);
System.out.println("AllocatedMemory: \t" + (Runtime.getRuntime().totalMemory() / 1024) + " Kb");
ostream.flush();
ostream.close();
}
}
在我的机器上输出为:
AllocatedMemory: 4096 Kb
AllocatedMemory: 1677721 Kb
所以这里程序使用1677 MB将一个简单的SVG文件转码为12600 * 12600 PNG文件。