7
votes

Java String Memory Fuite

Je ne suis pas expert Java.

Mon code lit un fichier dans une chaîne . Ce code est exécuté toutes les 5 minutes. La taille du fichier varie. Parfois, il est parfois 100, il est parfois 1000 lignes.

Je suis hors de la mémoire, après quelques jours.

La question que j'ai est, lorsque mes codes sortent de la portée de la Fonction de fichier de lecture , Java Portbage ramasse la chaîne?

Je suis assez confus en lisant sur Internet. Certaines personnes disent qu'il n'est pas supprimé et utilise stringbuffer . xxx


5 commentaires

Ça dépend. Les chaînes sont des objets. Avec des objets, cela dépend si l'objet est référencé par n'importe quoi (par exemple la valeur de retour de la méthode). Pouvez-vous poster du code?


Serait bien de voir le code et de ce que vous faites avec les cordes que vous avez lues. Essayez de nous donner un SSCCE < / a>


Je ne vois pas comment le code que vous avez posté pourrait courir pendant des jours.


La variable s n'est jamais nulle où il le vérifie depuis qu'il ajoute "ABCD" à celui-ci. Je pensais que cela lancerait une exception mais apparemment, il se transforme en "nullabcd"


@Anonymoose: Je ne vois pas comment ça ne pouvait pas courir indéfiniment :)


5 Réponses :


6
votes

Bonjour, je ne suis pas expert Java.

Tout le monde a quelque chose qu'ils peuvent apprendre.

Mon code lit un fichier dans une chaîne, ce code est exécuté toutes les 5 minutes. Maintenant, une taille de fichier de 100 lignes parfois 1000 lignes.

ne semble pas très grand ou très souvent. Ne devrait pas être un problème.

Je suis hors de la mémoire, après quelques jours.

Vous devriez pouvoir obtenir un vidage de tas et voir où vous êtes à court de mémoire et pourquoi.

question que j'ai est, lorsque mes codes sont hors de portée de la fonction de fichier de lecture. La poubelle Java ramasse-t-elle la chaîne?

Il peut être collecté quand il n'est plus accessible via une référence forte.

Je suis assez confus en lisant sur Internet Certains dit qu'il n'est pas supprimé et utiliser Stringbuffer

On dirait que vous êtes venu au bon endroit. Je n'ai jamais entendu cette question.


0 commentaires

5
votes

Votre méthode lue ne terminera jamais. Une fois que vous avez atteint la fin du fichier, vous continuez simplement d'ajouter la chaîne "nullabcd" à s , pour toujours.

Edit: oubliez que, s est ré-attribué à chaque fois. Néanmoins, je ne peux pas voir comment votre lue peut terminer.


1 commentaires

Oui, j'ai un fort sentiment que le code posté n'est pas le code réel qui a des problèmes.



2
votes

changer le programme comme ci-dessous pour consommer moins de mémoire. Une énorme source de consommation de mémoire est due à votre concaténation à chaîne répétée de s + = "ABCD"; code> - Évitez cela et vous aurez probablement plus de réduire de moitié votre consommation de mémoire (non testée - profiler vous-même si Vous voulez savoir).

public static void read(BufferedReader br) throws Exception {

    long length = 0;
    //String s; <--- change to the line below
    StringBuilder sb = new StringBuilder();
    while (true) {
        String s = br.readLine();
        if (s == null) {
            break;
        }
        //s += "abcd";  <--- change to the line below
        sb.append(s).append("abcd");
        length += s.length();
        //System.out.println(s);
    }
    System.out.println("Read: " + (length / 1024 / 1024) + " MB");
}


0 commentaires

4
votes

Le code que vous avez affiché ne fuit pas la mémoire. Cependant, la boucle tandis que (true) ne sera jamais terminée car s ne sera jamais null au point que vous le testez.


< p> permet de changer un peu pour le faire "travailler" xxx

Ce code ne fuit pas non plus que les chaînes créées dans la méthode seront toutes des candidats à la collecte des ordures Lorsque la méthode revient (si non auparavant).

Chaque fois que nous exécutons s + = ss; Une nouvelle chaîne est créée composée de tous les caractères actuellement en S et les caractères dans ss . En supposant qu'il y ait n lignes contenant une moyenne de caractères L, le s + = SS; sera appelé n Times, créera n chaînes et copiera en moyenne (n * l) ^ 2/2 caractères.


Cependant, il est une bonne raison de créer un stringbuilder et c'est pour réduire la quantité d'allocation de chaîne et de copie de caractères qui va au. Permet de réécrire la méthode d'utiliser un stringbuilder ; c'est-à-dire un remplacement de Stringbuffer qui n'est pas synchronisé. xxx

Cette version réaffectera le tableau de caractères interne de StringBuilder au plus log2 (n) fois et copiez au plus 2 * n * l caractères.


Résumé - Utilisation Le StringBuilder est une bonne idée, mais pas à cause des fuites de mémoire. Si vous avez une fuite de mémoire, il n'est pas dans le code d'exemples d'origine ni dans la version fixe.


0 commentaires

1
votes

Comme indiqué par d'autres, ce code ne se termine jamais. Il semble que le code que vous avez posté n'est pas le code d'origine que vous rencontrez des problèmes.

Difficile à diagnostiquer sans voir le code réel, mais les chaînes seront définitivement percubinées une fois qu'ils ne sont pas référencés à partir d'autres parties du code.

Wild Guess: appelez-vous ferme () sur vos lecteurs et vos intrigions une fois que vous avez terminé avec eux? Sinon, cela pourrait être la cause de vos erreurs de mémoire de mémoire.


0 commentaires