web-dev-qa-db-fra.com

S'agit-il d'une fuite de mémoire ou d'un faux positif?

Voici mon code:

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();
    }
}

Je reçois un avertissement dans new Scanner(a) qui dit (je compile avec jdk1.7.0_05.):

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

Suis-je en train de faire quelque chose de mal ou est-ce juste un faux avertissement?

38
dln385

Si vous divisez le code comme ceci, l'avertissement disparaîtra-t-il?

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

Oui, votre code présente une fuite de mémoire potentielle (mais pas réelle). Vous affectez la valeur de retour de useDelimiter(a) à la variable locale scanner, mais le résultat du constructeur est jeté. C'est pourquoi vous recevez l'avertissement.

En pratique, la valeur de retour de useDelimiter(a) est exactement le même objet que celui renvoyé par l'appel du constructeur, donc votre code ferme très bien la ressource. Mais c'est quelque chose que l'outil d'analyse du compilateur/code ne peut pas détecter car il devrait connaître l'implémentation useDelimiters pour cela.

Et un très bon outil d'analyse de code aurait dû vous montrer un avertissement supplémentaire, car vous fermez une ressource qui n'a pas été ouverte dans cette méthode (la valeur de retour de useDelimiter). Si vous aviez ces 2 messages ensemble, les symptômes auraient peut-être été plus clairs pour vous.

11
Bananeweizen

Avez-vous essayé:

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

Si cela ne fonctionne pas, vous devez ajouter a.close();

1
cl-r

Qu'est-ce qui vous donne cet avertissement? Vraisemblablement, il avertit parce que l'allocation/fermeture ne se fait pas dans un bloc try/finally, ce qui est généralement une mauvaise idée (dans ce cas spécifique, ce n'est pas un problème car la seule chose qui peut générer une erreur est le nouveau FileReader et s'il jette aucune ressource n'a été réellement allouée - mais cela peut changer avec un seul appel de méthode ..)

La fermeture d'un scanner ferme le flux sous-jacent (pour être exact tout ce qui se met en œuvre Closeable (oui BufferedReader le fait) donc le code est bien à part ça.

0
Voo