gpt4 book ai didi

带有动画 GIF 的 JavaFX OutOfMemoryError

转载 作者:搜寻专家 更新时间:2023-11-01 02:10:08 25 4
gpt4 key购买 nike

当我在浏览多个 GIF 后遇到一些 OutOfMemoryError 异常时,我正在创建一个具有图像浏览器的 JavaFX 2.0 应用程序,它应该能够显示动画 GIF。我设法将相关代码隔离到“GifCrasher”应用程序中:

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;

import javafx.scene.image.Image;


public class GifCrash {

// Settings:
private static long waitTime = 100; // msec
private static ArrayList<File> imageFiles = new ArrayList<File>() {{
add(new File("thrillercat.gif"));
}};

// Other:
private static long totalSize = 0;
private static long gifsLoaded = 0;

public static void main(String[] args) throws Exception {

while(!Thread.currentThread().isInterrupted()) {
// Read gif file:
File imageFile = GifCrash.imageFiles.get((int) (GifCrash.gifsLoaded % GifCrash.imageFiles.size()));
InputStream iStream = new FileInputStream(imageFile);
Image image = new Image(iStream);
iStream.close();

// Display info:
GifCrash.gifsLoaded++;
GifCrash.totalSize += imageFile.length();
System.out.println("Loaded " + imageFile + " (" + imageFile.length() + " bytes)");
System.out.println("GifCount\t=\t" + GifCrash.gifsLoaded);
System.out.println("TotalSize\t=\t" + Math.round((double) GifCrash.totalSize / (1024 * 1024)) + " MBytes (" + GifCrash.totalSize + " bytes)");
System.out.println();

// Wait?
if (GifCrash.waitTime > 0) {
Thread.sleep(GifCrash.waitTime);
}
}
}
}

这个简单的应用程序构建了 javafx Image 对象,实际上没有对它们做任何事情,因此,据我所知,这些对象应该被垃圾收集。在示例应用程序中,我通过每次重新加载相同的 GIF 而不是将其缓存在某个地方来模拟加载多个不同的 GIF(这样我就不必找到 >250MBytes 的 GIF 文件)。我还添加了一个可选的 waitTime 参数,以确保垃圾收集器有机会释放一些内存。但是,在 imageFiles 中使用动画 GIF 文件运行此应用程序一段时间后仍会产生 OutOfMemoryError(在我的例子中是在加载大约 250MBytes 的动画 GIF 之后)。使用 PNG 文件运行应用程序完全没有问题,似乎动画 GIF 是唯一的问题。

这些是我用于测试的图像:thrillercat.gifcatdestroyer.png .这是我在使用 thrillercat.gif 运行应用程序时得到的(截断的)输出:

Loaded thrillercat.gif (1203120 bytes)
GifCount = 1
TotalSize = 1 MBytes (1203120 bytes)

Loaded thrillercat.gif (1203120 bytes)
GifCount = 2
TotalSize = 2 MBytes (2406240 bytes)

...

Loaded thrillercat.gif (1203120 bytes)
GifCount = 225
TotalSize = 258 MBytes (270702000 bytes)

Loaded thrillercat.gif (1203120 bytes)
GifCount = 226
TotalSize = 259 MBytes (271905120 bytes)

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.sun.javafx.iio.gif.GIFImageLoader2.decodePalette(GIFImageLoader2.java:288)
at com.sun.javafx.iio.gif.GIFImageLoader2.load(GIFImageLoader2.java:191)
at com.sun.javafx.iio.ImageStorage.loadAll(ImageStorage.java:294)
at com.sun.javafx.iio.ImageStorage.loadAll(ImageStorage.java:244)
at com.sun.javafx.tk.quantum.PrismImageLoader2.loadAll(PrismImageLoader2.java:107)
at com.sun.javafx.tk.quantum.PrismImageLoader2.<init>(PrismImageLoader2.java:41)
at com.sun.javafx.tk.quantum.QuantumToolkit.loadImage(QuantumToolkit.java:607)
at javafx.scene.image.Image.loadImage(Image.java:942)
at javafx.scene.image.Image.initialize(Image.java:722)
at javafx.scene.image.Image.<init>(Image.java:625)
at GifCrash.main(GifCrash.java:27)

一如既往,我认为这是由于我的代码中的某些错误而不是错误,那么我在这里做错了什么?

如果这是一个错误,有没有办法解决它?即我需要能够在 JavaFX 窗口中显示大量动画 GIF(一次只能显示一个 GIF)。

谢谢!

最佳答案

只需使用 Java 8 ,您的示例程序适用于 Java 8 版本。

我在 Java 7u45 (OS X 10.8)(MacBook Air 2012,4gb ram)上尝试了示例程序,它在 71 次迭代后一直内存不足。

而对于 Java 8,程序在运行 5000 次迭代后从未耗尽内存:

Loaded /Users/lilyshard/dev/playfx/src/thriller-cat-o.gif (1203120 bytes)
GifCount = 10000
TotalSize = 11474 MBytes (12031200000 bytes)

我没有让您的程序在 Java 7u45 上运行的解决方法,而且在 Java 8 分支上进行的错误修复不太可能向后移植到 JavaFX 2.2。有时错误修复会根据用户请求通过 JavaFX 问题跟踪器向后移植,但这种情况很少见。

我的猜测是 JavaFX 2.2 gif 加载器中的一些错误已在为 Java 8 发布做准备时得到修复。

关于带有动画 GIF 的 JavaFX OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20314277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com