打开每个文件后出现Java内存泄漏

时间:2015-11-05 22:59:48

标签: java memory memory-management memory-leaks

我的应用程序存在问题,每次加载图像时都会增加它的RAM使用率。

解释

我使用JButton创建了一个传递GenericListener的帧。单击JButton后,它会提示文件选择,然后将文件加载到新创建的BufferedImage并调用GenericListener onExecute方法。

这种方法创建新类的实例,让我们称之为ImageProcessor。现在创建SwingWorker(仍然在GenericListener中)并在doInBackground方法中调用一些昂贵的方法,然后返回ImageProcessor中存储的字段,该字段在{done中获取1}}方法并传递给ImageView以更新显示的图像。

代码

public abstract class GenericListener<T> implements EventListener {
    abstract void onExecute(T param);
}

的JButton

 public void actionPerformed(ActionEvent e) {
        ...
            try {
                BufferedImage img = ImageIO.read(file);
                listener.onExecute(img);
            } 
        ...
    }

监听器的实现

final ImageProcessor imp = new ImageProcessor(param);
new SwingWorker<BufferedImage, Object>() {
    @Override
    protected BufferedImage doInBackground() throws Exception {    
        return imp.doSomeExpensiveStuff();
    }

    @Override
    protected void done()
    {
        try {
            imgView.changeImage(get());
        } catch(Exception e) {
            ...
        }
    }
}.execute();

最终问题

如何使应用程序释放以前保留的内存空间以加载新图像?

3 个答案:

答案 0 :(得分:0)

这些应该是垃圾收集,但它们不是,所以这意味着你要在某处保留图像的引用。

答案 1 :(得分:0)

将值设置为null以确保它不再引用,然后手动调用垃圾收集器(System.gc)。您还可以使用jconsole来了解内存的使用方式。如果您需要更多信息,那么堆转储和对它的分析将告诉您哪些对象没有被释放。

有关解决内存泄漏的更多信息:http://www.oracle.com/technetwork/java/javase/memleaks-137499.html#gbyvi

答案 2 :(得分:0)

为了从存储的变量中释放内存,只需将其设置为null。

在你的情况下,你需要将img保留在某个地方,可能需要使用最终修饰符(因为必须在最终字段上执行匿名调用)。

img = null;

内存将通过下一个GC释放:)