FileInputStream文件读取循环中的内存泄漏

时间:2011-02-02 09:10:07

标签: java memory-leaks fileinputstream

我们使用简单,简单,简单的代码面临内存泄漏,如下所示。 该代码旨在从源获取文件,使用每个文件执行某些操作并继续。 这个简单的代码总是使用相同的文件,但行为没有改变。

package it.datapump.main;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;


public class TifReader {

public static void main (final String[] a){

    for (int i = 0; i < 100000; i++) {
        try {
            getBytesFromFile(new File("test.tif"));
            Thread.sleep(1000);
            System.gc() ;
        } catch (Exception ex) {
        }
    }
}

public static byte[] getBytesFromFile(File file) throws IOException {
    InputStream is = new FileInputStream(file);
    long length = file.length();

    byte[] bytes = new byte[(int)length];
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }
    is.close();

    // Do something with the read bytes
    //

    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }
    return bytes;
}
}

现在......我们只是看不出这个代码消耗内存到顶部的有效原因,最后会抛出OutOfMemoryError异常。
有什么想法吗?

更多东西
问题出现在Java Development Kit Version 6 Update 23上,但它不适用于JRE 1.7

4 个答案:

答案 0 :(得分:2)

这段代码运行正常(除了创建新文件这么多次没有意义)。

我在一个循环中运行你的代码1000万次并且它没有产生OOME。事实上,它的内存使用量一直保持在50Mb左右。

所以,我认为问题应该是别的。

答案 1 :(得分:1)

我会针对像Visual VM这样的探查器运行您的代码,并查看内存耗尽的位置。

我猜测“带字节代码的东西”可能会导致问题。通常不建议调用System.gc(),因为garabge收集器应该在调用它时知道它自己。

答案 2 :(得分:0)

由于你在每次迭代时都有效地丢弃了从文件读取的字节,我认为没有理由获得OOME,除非文件的大小超过了JVM进程的默认Xmx(只是一个思考过程,因为我知道TIF文件与其他图像格式相比,因其巨大的尺寸而臭名昭着。)

另外,打印出迭代编号。你是否总是以相同的迭代次数获得OOME?或者是你“使用”从文件流中读取的字节?

答案 3 :(得分:0)


在浪费时间并对此进行操作后,我们发现问题是由于包装在目标机器上的安装方式 我们的程序员构建了一个可运行的jar,包含所有需要的jar,而不是使用目标机器上安装的alt。 所以......“某些东西”是不同的,即使我们实际上并不知道什么,而且现在的程序不会再失去记忆。

有人可以向我解释一下吗? (我不得不说我是一名C / C ++开发人员,而不是Java开发人员,而且我正在撰写关于我的同事的工作)。