2011-02-02 103 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?還是你在「使用」從文件流中讀取的字節?