web-dev-qa-db-ja.com

これはメモリリークですか、それとも誤検知ですか?

これは私のコードです:

_import Java.io.BufferedReader;
import Java.io.FileNotFoundException;
import Java.io.FileReader;
import Java.util.Scanner;

public class temp {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedReader a = new BufferedReader(new FileReader("a"));
        Scanner scanner = new Scanner(a).useDelimiter(",");
        scanner.close();
    }
}
_

new Scanner(a)に次のような警告が表示されます(jdk1.7.0_05でコンパイルしています)。

_Resource leak: '<unassigned Closeable value>' is never closed.
_

私は何か間違ったことをしていますか、またはこれは単なる誤った警告ですか?

38
dln385

このようにコードを分割すると、警告は消えますか?

  Scanner scanner = new Scanner(a);
  scanner.useDelimiter(",");
  scanner.close();
59
Francis Upton

はい、コードには潜在的な(ただし実際の)メモリリークがあります。 useDelimiter(a)の戻り値をローカル変数scannerに割り当てますが、コンストラクターの結果は破棄されます。そのため、警告が表示されます。

実際には、useDelimiter(a)の戻り値は、コンストラクター呼び出しから返されたものとまったく同じオブジェクトなので、コードはリソースを正常に閉じます。しかし、これはコンパイラ/コード分析ツールcannotがuseDelimiters実装を知る必要があるため検出するものです。

また、このメソッドで開かれていないリソース(useDelimiterの戻り値)を閉じているため、非常に優れたコード分析ツールが追加警告を表示するはずです。これら2つのメッセージが一緒にあった場合、症状はより明確になっている可能性があります。

11
Bananeweizen

試しましたか:

_Scanner scanner = new Scanner(new BufferedReader(new FileReader("a"))).useDelimiter(",");
_

動作しない場合は、a.close();を追加する必要があります

1
cl-r

この警告を与えているのは何ですか?おそらく、割り当て/終了はtry/finallyブロックで行われないため警告されますが、これは一般に悪い考えです(ただし、エラーをスローできる唯一のものは新しいFileReaderであり、実際に割り当てられたリソースはスローされませんが、1回のメソッド呼び出しで変更できます。

スキャナーを閉じると、基礎となるストリームが閉じられます(正確には、Closeable(はいBufferedReaderは実装されます)。それ以外は問題ありません。

0
Voo