Question

Nous avons une application plutôt volumineuse et complexe écrite en Java qui s'exécute par-dessus le paquet Gridgain. Le problème que je rencontre est que cette application restera là à traiter les demandes pendant environ un jour avant que chaque demande ne commence, ce qui entraîne une exception de type java.nio.channels.ClosedByInterruptException.

Je suppose que l'application ne publie pas de descripteurs de fichiers. Après une journée d'utilisation continue, elle est épuisée et ne peut plus continuer à traiter les demandes (chaque demande nécessite la lecture de plusieurs fichiers à partir de chaque nœud de la grille). Nous avons encapsulé la plupart de nos opérations d’entrées / sorties de fichiers dans des classes telles que celle-ci

package com.vlc.edge;

import com.vlc.common.VlcRuntimeException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public final class BufferedReaderImpl implements BufferedReader {
    private java.io.BufferedReader reader;

    public BufferedReaderImpl(final String source) {
        this(new File(source));
    }

    public BufferedReaderImpl(final File source) {
        try {
            reader = new java.io.BufferedReader(new FileReader(source));
        } catch (FileNotFoundException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public BufferedReaderImpl(final Reader reader) {
        this.reader = new java.io.BufferedReader(reader);
    }

    public String readLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public void close() {
        try {
            reader.close();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }
}

Je pense que le problème est que cette conception ne libère pas explicitement le descripteur de fichier, ma solution proposée consiste à ajouter une méthode de finalisation comme celle-ci

    protected void finalize() throws Throwable
    {
        reader.close();
        super.finalize();   
    }

qui le fera explicitement. La question (enfin) est de savoir si cela est susceptible d'avoir un effet. Des classes telles que java.io.BufferedReader disposent-elles déjà d’un mécanisme permettant de traiter ce type de problème?

EDIT: Les moyens de vérifier s’il s’agit bien du problème sont également très appréciés. Par exemple, existe-t-il un moyen d’interroger une machine virtuelle Java en cours et de demander des informations sur les allocations de descripteurs de fichier?

Était-ce utile?

La solution

Il est inutile de remplacer finalize () . Si le descripteur est en train de collecter et de finaliser des déchets, l'instance de java.io.BufferedReader va également l'être.

Il est possible (selon les spécifications) que le descripteur soit en train d'être collecté, mais pas finalisé, mais cela n'est pas très probable.

Vous pouvez essayer d’utiliser des PhantomReference pour nettoyer les descripteurs de fichiers inutilisés, mais j’estime que vos instances de BufferedReaderImpl sont toujours référencées quelque part (par exemple, les valeurs dans un < code> Mappez à partir des noms de fichiers pour ouvrir les descripteurs) et c’est ce qui empêche leur fermeture (dans ce cas, les finaliseurs ne vous aideront pas.)

Autres conseils

Les finaliseurs ne peuvent pas être appelés. Ce n'est pas une bonne approche pour la gestion des ressources. La construction standard en Java pour cela est:

InputStream in = null;
try {
  in = ...;
  // do stuff
} catch (IOException e) {
  // error
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
  in = null;
}

Vous pouvez vouloir insérer ces poignées dans une classe, mais ce n'est pas une approche robuste.

La spécification Java indique qu'il n'est pas garanti que " finalize () " sera exécuté. Votre code doit explicitement fermer FileReader vous-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top