【发布时间】:2012-06-05 23:05:23
【问题描述】:
我在使用 BufferedImage 时遇到了奇怪的问题,在某些情况下它会占用所有可用的系统内存(3GB、1.5GB 可用)。
我创建了一个简单的包装器,并像这样使用它:
public ImageWrapper(final byte[] bytes) throws ImageWrapperException {
this(new ByteArrayInputStream(bytes));
}
public ImageWrapper(final ByteArrayInputStream bis) throws ImageWrapperException {
try {
image = ImageIO.read(bis);
bis.close();
} catch (IOException e) {
throw new ImageWrapperException(e);
}
}
(我已验证即使使用image = ImageIO.read(file); 也会发生这种情况)
在第一个“无法分配内存”之前,我没有遇到任何异常。
由于某种原因,在读取特定类型的图像时,图像的读取最终会消耗掉所有的系统内存。我说的不是堆,而是系统内存。
它只发生在某些环境中 - 它不会发生在我的 OSX 上,但它会发生在我的 Debian 服务器上。
- 您知道为什么会发生这种情况吗?
- 有没有 BufferedImage 的替代品,可能效果更好?
- 有问题的机器是虚拟服务器。会不会是它的配置造成的?
谢谢
编辑:
- 示例图片:http://cl.ly/1P430l0V1g133r0C291J
- 它只是第一个也是唯一一个会产生这个的实例。
- 我刚刚验证了它也发生在:
image = ImageIO.read(file);- 我开始认为,它一定是 Java 之外的东西 - 一些有问题的本机库...
EDIT2:
所以问题出在文件系统上——我有一个 7GB 的目录,里面有数千张图像。当我尝试读取文件时,它会消耗所有内存 - 我想这是某种文件系统问题。
【问题讨论】:
-
什么具体类型的图片?您可以发布一张此类图像的二进制 1:1 副本吗?您如何在周围的代码中使用
ImageWrapper,有多少实例等?请发布更多代码。 -
特别是如果您调整大小,请将 ImageIO.read 拆分为使用该图像类型可用的第一个 ImageReader。这规避了 BufferedImage 内存使用。顺便提一句。在 finally 块中执行 bis.close()。
-
菲利普:看看我的更新。 Joop:即使没有任何调整大小或保存,也会发生这种情况。即使我没有执行 bis.close(),我也看不出任何原因,为什么该进程会消耗 1.5 GB 的内存。
-
@Vojtěch:您如何准确测量内存使用情况? Linux 上的内存测量并不像看起来那么简单......
-
你是说如果你写的类有一个main方法 public static void main(String[] args) { Image image = ImageIO.read(args[0]);并传入您链接的图像的文件名,它会为您复制吗?
标签: java image memory-leaks bufferedimage