【问题标题】:How to read many images in java without memory leak如何在没有内存泄漏的情况下在java中读取许多图像
【发布时间】:2014-11-19 09:24:07
【问题描述】:

我需要读取许多图像才能一个接一个地处理它们。一开始我使用IO库读取每张图片:

File outputfile = new File(uri);
BufferedImage imgBuff = ImageIO.read(outputfile);
imgBuff.flush();
imgBuff = null;
outputfile = null;

但是它占用了大量内存并且我的进程崩溃了。在做了一些研究之后,我发现使用 java IO 库读取许多图像存在很多问题。我使用这个简单的程序来验证内存泄漏是由使用此图像http://tinyurl.com/ku3ff7w 读取图像引起的:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.junit.Test;

public class MemoryLeakTest {

  static File outputfile = null;
  static BufferedImage imgBuff = null;

  public static void main(String args[]) {
    String uri = "/home/user/Pictures/image.jpg";
    outputfile = new File(uri);

    for (int i = 0; i < 15000; i++) {
      outputfile = new File(uri);
      try {
        imgBuff = ImageIO.read(outputfile);


      } catch (IOException e) {

        e.printStackTrace();
      } finally {
        if (imgBuff != null) {
          imgBuff.flush();
          imgBuff = null;
        }
        outputfile = null;
      }
    }
  }
}

我也尝试过使用 ImageJ 库,但是将图像转换为 BufferedImage 时出现了同样的问题:

ImagePlus bb = op.openImage(uri);
imgBuff = bb.getBufferedImage();
bb.killStack();
bb.flush();
bb.close();

我想我可以将图像读取为字节数组,这样可以解决问题,但解决方案并不理想。有谁知道是否有任何库或方法可以在 Java 中读取许多图像而不会耗尽内存?

【问题讨论】:

  • 我修改了您的示例以避免代码重复,引入了 finally 块(我认为这更好,但在这种情况下并不真正相关)。运行它没有任何问题。据我所知,没有内存泄漏。我什至试图通过使用-Xmx16m 命令行选项来强制它。也许您需要特定的 Java 版本、参数或特殊的 JPEG 来重现问题?
  • 感谢您的回复。这是我正在使用的图像tinyurl.com/ku3ff7w。也许是因为那张图片要大得多。
  • @Victoria - 我只是用 2mb 的图像运行代码没有问题 - 但是我已经将我的最大堆空间增加到 1GB,并且通过插入一些对 Runtime.getRuntime().freeMemory() 的调用,我可以看到程序使用相当大的一部分(〜50%)。你有没有分析过自己的内存使用情况?尝试增加你的堆大小 (-Xmx),也许每隔几次迭代就调用一次System.gc(),看看是否有帮助。
  • 即使使用大图像,我也可以使用-Xmx16m 运行示例。那里没有内存泄漏。我认为您要么使用了可能存在错误的特殊 Java 版本,要么只是混淆了“内存泄漏”和“高内存使用”这两个术语。分析是一个好主意,可以找出内存卡在哪里。在代码中插入System.gc() 通常是个坏主意,因为Java 会在某个时候释放垃圾收集器可收集的任何内存。如果发生内存泄漏,内存将无法回收。

标签: java image memory-leaks


【解决方案1】:

我的解决方案是使用 img4Java(ImageMagick 命令行的 java 接口)。
通过这种方式,我将图像操作委托给外部进程,从而释放 JVM 以释放内存。

http://im4java.sourceforge.net/http://www.imagemagick.org/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2023-01-05
    • 2021-12-19
    • 2021-12-02
    • 2011-04-16
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多