【问题标题】:Java OutofMemory Strange ErrorJava OutofMemory 奇怪的错误
【发布时间】:2013-03-23 15:43:33
【问题描述】:

我已经使用以下命令从命令行启动了我的jar

java -Xms1200m -Xmx1500m -jar xxx.jar

我正在创建大小为 12600 * 12600 的 BufferedImage 意味着它需要

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 分钟??

我的电脑配置如下

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)

请帮我解决这个问题。

下面是带有调试消息的异常堆栈tarce。

在运行上述代码之前,我将 VM 参数更改为以下

java -Xms900m -Xmx1024m -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=70 -jar myjar.jar

从 SVG 阅读器构建 XML 文档.... 从 SVG Reader 构建完成的 XML 文档.... 将修改后的 XML 文档转换为字符串编写器...... 修改后的 XML 文档到字符串编写器的转换完成...... claimBytes 766 Avaialbel 字节 900189232 内存统计------------------------ 总内存为字节:912326656 总内存为兆字节:870 已用内存为字节:9308384 已用内存为兆字节:8 可用内存为字节:900189096 可用内存为兆字节:858


转码开始于:Sun Mar 24 11:09:59 IST 2013

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)

【问题讨论】:

  • @TReddy 如果你知道答案,那你为什么不给呢?
  • @Maroun 你知道答案吗?
  • t是什么类型的对象?
  • @ecbrodie 哦,对不起,我忘了提到 T 是来自 Apache Batik 库的 PngTransCoder。
  • 您应该使用 -XX:+HeapDumpOnOutOfMemoryError 标志,并分析堆转储。 YourKit 是用于此目的的出色工具,但 JVisualVM 也易于使用且免费(您可以在 JDK 文件夹中找到它)。

标签: java performance memory-management


【解决方案1】:

即使原始未编码图像仅填充大约 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 文件。

【讨论】:

  • 您的 PC 中有多少内存(以 GB 为单位)?在您的 PC 上运行以上代码需要多长时间?
  • 好的,我在其他具有更高内存的电脑上尝试过它并且它可以工作,现在你能给我这个代码运行没有任何问题的电脑配置吗?您的 JDK 配置和生成(转码)PNG 在磁盘上的文件大小(以 MB 为单位)?
  • 我的电脑中有 8 GB。我在程序中编码的文件来自维基百科:[link]en.wikipedia.org/wiki/File:SVG-logo.svg,大约需要 20 秒。在我的 PC 上处理,输出大小为 1.1 MB 的文件。我在 Eclipse 中运行程序,没有特殊选项。
  • 另一件事用多色图像测试你的程序,请告诉我生成的 png 文件的大小和生成文件所需的时间。你可以在这里找到大量的多色 svg raphaeljs.com
  • 为什么不自己做呢?
猜你喜欢
  • 2015-11-12
  • 2012-05-03
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
相关资源
最近更新 更多