2011-02-02 105 views
3

我们正在面对一个简单,简单,简单的代码如下所示的内存泄漏。 该代码旨在从源获取文件,使用每个文件做一些事情并继续。 这个简单的代码总是使用相同的文件,但行为不变。现在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开发套件版本6更新23,但它不会对JRE 1.7

+0

我是否正确 - 正确* this * snippet创建了一个OOM错误,OOM与注释的“使用读取字节做某事”部分没有关系?没有例外被抛出? – 2011-02-02 09:24:32

+0

@Andreas_D,没有兴趣分析片段。这是完全错误的阅读文件的方式。 – 2011-02-02 09:25:53

+0

@Vladimir:恕我直言,你需要尊重OP发布的问题,而不是强迫你通过。顺便说一句,这不是一个错误的方式,它只是一种循环方式。 – 2011-02-02 09:30:45

回答

0


在发现问题后,我们发现问题在于目标机器上的软件包是如何安装的。
我们的程序员构建了一个可运行的jar包含每个需要的jar,而不是使用已经安装在目标机器上的jar。 所以......“某些东西”是不同的,即使我们实际上不知道什么,现在的程序也不会松动记忆。

有没有人可以向我解释这一点? (我必须说我是C/C++开发人员,而不是Java开发人员,而且我正在写关于我的同事的工作)。

2

此代码应运行正常(除了一个事实,即创建新的文件,所以很多时候品牌没有意义)。

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

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

1

我会运行你的代码,像Visual VM这样的分析器,看看内存在哪里用完。

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

0

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

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