2

我正在尝试运行一个草图,该草图应该在封面流动画中显示图像(png,大小在 100kb 和 1.5mb 之间,总共 55.4mb)。它适用于大约 10 张图像,但使用更多我会出现内存不足错误。我正在将图像文件名加载到一个字符串数组中,如下所示:

String[] names = {"00.jpg", "01.jpg", "02.jpg"};

然后他们像这样被加载到草图中:

covers = new Cover[names.length];
  for (int i = 0; i < covers.length; i++ ) {
  covers[i] = new Cover(names[i]);
}
initCovers();

涵盖类:

class Cover {
  PImage img;

Cover( String name ) {
img = loadImage(name);

public void drawCover() {
  beginShape();    
    textureMode(NORMALIZED);
    texture(img);
    vertex(-300, -300, 0, 0, 0);
    vertex( 300, -300, 0, 1, 0);
    vertex( 300,  300, 0, 1, 1);
    vertex(-300,  300, 0, 0, 1);
  endShape();

当我运行草图时,我的内存(8gb)在几秒钟内就被填满了,草图甚至没有加载,它只是崩溃了。当我用大约 10 张图像开始草图时,一切正常(大约 1.5gb 的 ram 使用量)。

我的问题是:为什么它使用这么多内存?正常吗?有没有办法让它运行时内存效率更高(例如,释放当前未显示的图像内存,因为我们一次只能在屏幕上看到大约 3 个图像)。

编辑:我认为问题在于在封面类中,每次调用它都会创建一个新的 PImage 。这可能吗?

内存中的图像大小:宽度 * 高度 *(颜色深度/8),所以对于我的图像(1575y1969,24 位)来说,这将是 8.9mb。乘以 91 图像:仅用于图像的内存使用量约为 807mb。

4

4 回答 4

3

现在我更好地理解了用例,我建议更改整个方法。

盖流图形用户界面

您尝试模拟的应用程序类型(例如上面看到的)不会在应用程序加载整个图像时立即加载。被呈现。相反,他们会首先阅读将要呈现给用户的一小部分图像。当用户接近该组的末尾时,软件会在序列开始时刷新一些图像(如果内存紧张)并在最后加载一些图像。

于 2012-08-01T00:08:51.653 回答
1

尝试增加 JVM 堆空间

java -Xmx1024m

(是的,我知道,1gig 是“有点”过度,但经过一些实验,这个值可以减少)

正如@millimoose 所说,Java 加载的图像在加载时会被解压缩到内存中,因此即使磁盘上 100kb 的小图像在解压缩时也会突然占用 mb 的 RAM。当您也开始处理 Alpha 通道时,它变得更加复杂。

于 2012-07-31T22:50:55.373 回答
1

压缩图像的大小不能很好地指导内存要求。

以像素为单位的大小更好。例如,具有 8 兆像素分辨率的现代相机照片需要至少 32mb 的内存来表示。如果您正在使用摇摆来处理这种尺寸的图像,那么至少是两倍或三倍。很容易吞噬大量内存。

此外,Java 的内部内存管理也不能很好地处理这种大小的块。

于 2012-07-31T23:00:24.930 回答
0

我会说尝试使用单个临时 Cover 作为句柄将它们绘制到一个组件上,而不是让 N 多个对象挂在周围?如果您需要在绘制时间后与图像交互,只需保留一些有关其绘制位置和尺寸的简单元数据,然后使用点击事件 x,y 等来查找给定图像以允许您使用它。

于 2012-07-31T22:51:58.333 回答