java OutOfMemoryError avec stringbuilder
-
19-09-2019 - |
Question
Je reçois OutOfMemoryError java quand je l'appelle cette méthode - je l'utilise dans une boucle pour analyser de nombreux fichiers volumineux dans l'ordre. je suppose que result.toString()
ne reçoit pas correctement les déchets ramassés lors de la boucle. si oui, comment dois-je résoudre ce problème?
private String matchHelper(String buffer, String regex, String method){
Pattern abbrev_p = Pattern.compile(regex);//norms U.S.A., B.S., PH.D, PH.D.
Matcher abbrev_matcher = abbrev_p.matcher(buffer);
StringBuffer result = new StringBuffer();
while (abbrev_matcher.find()){
abbrev_matcher.appendReplacement(result, abbrevHelper(abbrev_matcher));
}
abbrev_matcher.appendTail(result);
String tempResult = result.toString(); //ERROR OCCURS HERE
return tempResult;
}
La solution
écrit de cette façon, vous aurez besoin d'environ octets de mémoire 6 pour tous les caractères dans le fichier.
Chaque caractère est deux octets. Vous avez la première entrée, la sortie substitué (dans le tampon), et vous demandez une troisième copie lors de l'exécution de mémoire.
Si le fichier est encodé dans quelque chose comme ASCII ou ISO-8859-1 (un seul caractère octets de codage), cela signifie qu'il sera six fois plus grande que dans la mémoire sur le disque.
Vous pouvez allouer plus de mémoire au processus, mais une meilleure solution pourrait être de traiter l'entrée « par fractions » -Lire, numérisation et écrire les données sans le charger en mémoire tout à la fois.
Autres conseils
Si vos fichiers à traiter sont très grandes, disent plus que quelques centaines de Mo, alors vous devriez vraiment aller avec le traitement des flux au lieu de cette façon « chargement tout en mémoire », tout comme @erickson suggéré.
Dans le cas contraire, il y a quelques choses que vous pouvez essayer, tout pour réduire l'utilisation de la mémoire autant que possible:
- Essayez agrandir correctement la taille de votre tas si pas encore (le cas échéant).
- Donner
StringBuffer
une taille initiale même que la longueur de laString
debuffer
donné. Cela devrait réduire l'utilisation de la mémoire inutile tout en élargissant leStringBuffer
dans le processus. Je suppose qu'il est seulement de remplacer certains mots de la chaîne d'origine et devrait être plus ou moins la même longueur. - Si possible, vous pourriez peut-être renvoyer l'objet
StringBuffer
généré à la place. Appelant satoString()
seulement après que vous vous débarrasser de l'objetString
d'origine.
Je pense le problème avec StringBuilder.append()
. Lorsque matcher séquence de caractères ajoute au constructeur.
Comme expliqué dans l'article sur le OutOfMemoryError avec StringBuilder / StringBuffer , il est un problème connu qui append () va doubler la capacité si chars
tampon interne si la capacité ne suffit pas.
Aller pour les flux comme suggéré par Erickson.
Je suis d'accord avec les autres réponses ... mais ... tout simplement parce que l'exception se produit, il ne le fait pas nécessairement signifie qu'il est le problème. Vous pouvez très bien être fuite de mémoire ailleurs et que se trouve être l'endroit où il est révélé. Vous devez exécuter un profileur pour examiner l'utilisation de la mémoire et de vérifier exactement ce que les objets ne sont pas collectés.
Oui! Ne pas en mémoire tampon dans la mémoire sinon vous tomberez sur spécialement si vous allez plus 2MB sur E / S.
Lien recommandé pour la fixation et ajouter du texte: http: // java.ittoolbox.com/documents/appending-data-to-a-file-18786
Vous pouvez essayer de retourner un StringBuffer
et la mise à null
après utilisation.