[英]Java OutofMemory Strange Error
我使用以下命令從命令行啟動了我的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
Exception。
問題是什么 ? 是處理問題還是堆問題? 為什么需要34分鍾?
我的PC配置如下
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)
即使原始的未編碼圖像只能填充大約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文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.