处理:内存不足错误

时间:2011-04-27 20:31:31

标签: java user-interface processing out-of-memory

我正在使用Processing。这是我的全部素描:

import guicomponents.*;

PImage backgroundImage;

void setup() {      
  size(911, 715); 
  backgroundImage = loadImage("Floorplan.png");
}
void draw() {
  background(backgroundImage);
  GImageButton[] buttons = {
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10),
    new GImageButton(this, null, "wm.png", 1, 10, 10)
  };
}

(这只是一个演示来说明我遇到的问题。)如果运行的时间足够长,将生成OutOfMemoryError

An OutOfMemoryError means that your code is either using up too much memory
because of a bug (e.g. creating an array that's too large, or unintentionally
loading thousands of images), or that your sketch may need more memory to run.
If your sketch uses a lot of memory (for instance if it loads a lot of data files)
you can increase the memory available to your sketch using the Preferences window.
Exception in thread "Image Fetcher 2" java.lang.OutOfMemoryError: Java heap space
An OutOfMemoryError means that your code is either using up too much memory
because of a bug (e.g. creating an array that's too large, or unintentionally
loading thousands of images), or that your sketch may need more memory to run.
If your sketch uses a lot of memory (for instance if it loads a lot of data files)
you can increase the memory available to your sketch using the Preferences window.
    at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
    at java.awt.image.Raster.createPackedRaster(Raster.java:458)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015)
    at sun.awt.image.ImageRepresentation.createBufferedImage(ImageRepresentation.java:230)
    at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:528)
    at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:120)
    at sun.awt.image.PNGImageDecoder.sendPixels(PNGImageDecoder.java:531)
    at sun.awt.image.PNGImageDecoder.produceImage(PNGImageDecoder.java:452)
    at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:246)
    at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
    at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
Exception in thread "Animation Thread" java.lang.OutOfMemoryError: Java heap space
    at processing.core.PImage.<init>(Unknown Source)
    at processing.core.PApplet.loadImageMT(Unknown Source)
    at processing.core.PApplet.loadImage(Unknown Source)
    at processing.core.PApplet.loadImage(Unknown Source)
    at guicomponents.GImageButton.getImages(GImageButton.java:136)
    at guicomponents.GImageButton.<init>(GImageButton.java:100)
    at gimage_demo.draw(gimage_demo.java:35)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:619)

为什么会发生这种情况?当数组在draw()末尾超出范围时,内存是否会收集垃圾?

我试图让按钮抽搐时遇到这个问题。我找不到改变其位置的方法,所以我只是在我想要的新位置创建了一个新的位置。有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

  

为什么会这样?当数组在draw()结束时超出范围时,内存是否会收集垃圾?

唯一保证的是buttons数组在超出范围时符合垃圾回收的条件。对于GImageButton个对象及其成员,它取决于GImageButton构造函数的副作用。

确保构造函数不会在第一个参数(在您的情况下为this)中“注册”自身,并且没有缓存,或者GImageButton没有泄漏它来自构造函数的this引用等。

答案 1 :(得分:1)

查看代码(http://code.google.com/p/gui4processing/source/browse/trunk/GUI4Processing/src/guicomponents/G4P.java?r=331)显示所有GImageButton实例存储在静态HashMap中。我看不出处理它们的方法(尽管我看起来并不那么难)。因此他们没有资格获得垃圾收集。

我希望答案是创建按钮一次(例如在setup中),然后在draw中使用它们(除非您能找到等效的dispose()方法)。< / p>