2011-02-02 42 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の例外をスローするための正当な理由を見ることができません。
もっと

何か
問題はアップデート23のJava Development Kitバージョン6を使用して発生するが、それはJRE 1.7

+0

正確には*この*スニペットでOOMエラーが生成され、OOMはコメント付きの「読み込みバイトで何かする」部分には関係しません。例外も例外ではありませんか? –

+0

@Andreas_D、スニペットの分析に興味はありません。これは完全に間違ってファイルを読む方法です。 –

+0

@Vladimir:IMHO、あなたはあなたの方法を強制するのではなく、OPによって投稿された質問を尊重する必要があります。そして、それは間違ったやり方ではなく、ちょうど回り道です。 –

答えて

0


これに時間と負担をかけた後、この問題はターゲットマシンにパッケージがインストールされているために発生しています。
プログラマーは、ターゲットマシンにインストール済みのものを使用する代わりに、必要なすべてのjarを含む実行可能なjarファイルを作成しました。 ...「何か」は違っていました。たとえ実際に何が分かっていなくても、今は手続きがもう記憶を失わないのです。

誰でも私にこのことを説明できますか? (私はC/C++開発者でJavaではなく、私の同僚の仕事について書いています)。

2

にこのコードは、非常に多くの倍になり、新しいファイルを作成しているという事実を除いて(罰金実行する必要はありませんも意味ない)。

ループを1000万回実行しても、OOMEが生成されませんでした。実際にはメモリ使用量は約50Mbで一定でした。

だから、私は問題が他のものでなければならないと思います。

+0

非常に良い...あなたはどのIDEを使用しているのか説明できますか?どのようなシナリオですか?私は、JRE/JDKのバージョンなどを意味しますか? 問題はマシンによってのみ発生し、他のマシンでは発生しないため、非常に似たようなことに直面しました。 –

+0

OS X上の最新のJava SDK 1.6。IdeはIntellij IDEA 10です。 –

1

Visual VMのようなプロファイラに対してコードを実行し、メモリがどこで使い果たされているかを見てみましょう。

"バイトコード付きのもの"が問題を引き起こす可能性があると推測しています。また、ガベージコレクタは呼び出されるべきときに自分自身を知る必要があるので、System.gc()を呼び出すことは一般的には推奨されていません。

+0

私が言ったように、サンプルのコードでは、 "何か"の点で何も行われませんが、問題はすべて同じになります。 –

+0

大丈夫です。私は私の答えを書いている間、それらのコメントを逃した。あなたがJava 1.6を使用している場合、あなたはビジュアルVMを使用することができます。それはnetbeansと日食のためのプラグインを持っています。 –

0

各反復でファイルから読み取ったバイトを効果的に捨ててしまうので、ファイルのサイズがJVMプロセスのデフォルトのXmxを超えない限り、OOMEを取得する理由はありません。私はTIFファイルが他のイメージフォーマットと比較して大規模なサイズで有名であることを知っています)。

また、繰り返し番号を印刷します。常に同じ繰り返し回数でOOMEを取得しますか?または、ファイルストリームから読み取ったバイトを「使用している」ということですか?

+0

反復回数は、JVMに与えるメモリ量に比例します。したがって、特定のファイルが問題を引き起こすとは思われません。 –

+0

私はこれらのTIFファイルがかなり小さいことを忘れてしまいました。 –

関連する問題