6
votes

Problèmes de mémoire avec String.Split ()

Mes programmes ont actuellement des problèmes de mémoire et lors de la vérification de l'application, nous avons découvert que la méthode string.split () utilise beaucoup de mémoire. J'ai essayé d'utiliser un StreamTokenizer , mais cela semble que cela rend les choses encore plus complexes.

Y a-t-il un meilleur moyen de scinder de longs strings en petites qui utilise moins de mémoire que la méthode string.split () ? < / p>


5 commentaires

Combien de fois avez-vous réellement divisé cette chaîne? Pouvez-vous montrer du code?


Avez-vous essayé StringTokenizer à Java? docs.oracle.com/javase/1.4. 2 / Docs / API / Java / Util / ...


Hey je vais essayer StringTokenizer, merci.


Split crée beaucoup de déchets mais n'utilise pas beaucoup de mémoire. Je soupçonne que votre problème de mémoire est ailleurs. Que voyez-vous lorsque vous utilisez un profileur de mémoire?


Comme je me suis souvenu, j'utilise la chaîne [] STR pour faire référence à la valeur renvoyée de String.Split. puis mettre chacune des chaînes de STR dans HASHMAP comme clé. C'est peut-être la cause du problème de la mémoire.


4 Réponses :


0
votes

division ne crée pas de nouvelles chaînes, il utilise substrant en interne, ce qui crée une nouvelle chaîne objet qui pointe vers la sous-chaîne d'origine de la chaîne d'origine, sans copier le sous-jacent Char [] .

SA SE SE SE SA SUR LE TRANSPORTE DE CRÉATION DES OBJETS, il ne faut pas avoir d'impact énorme d'un point de vue de la mémoire.

PS: StringTokenizerzer utilise la même technique de sorte qu'il produirait probablement les mêmes résultats que la scission.

EDIT

Pour voir que c'est le cas, Vous pouvez utiliser le code exemple ci-dessous. Il se divise abc, def dans abc et def imprime ensuite le fichier charlent [] de la chaîne d'origine et de Les chaînes fractionnées - la sortie montre qu'ils sont tous identiques.

sortie: xxx

code: xxx


3 commentaires

Dans la méthode de sous-chaîne, il créera enfin une nouvelle chaîne avec la nouvelle chaîne (offset + BeginIndex, endindex - BeginIndex, valeur), et lorsque la nouvelle chaîne (XXX) a été appelée, le code JVM fera une copie de char [ ] Valeur dans la piscine de cache une fois qu'elle s non existé, est-ce correct?


Non, la nouvelle chaîne n'utilisera le même char [] comme l'original. Maintenant, si vous vous séparez pour garder une petite partie de la chaîne d'origine, vous porterez la chaîne entière autour de votre référence à son Char [] dans chacune des sous-chaînes.


Désolé, je viens de lire le code source et j'avais tort. Il utilise la copie pour améliorer la performance de la mémoire.



0
votes

Split peut-être la mémoire de l'aspect si vous voulez simplement utiliser un ou plusieurs tableaux de la longue chaîne. La longue chaîne sera toujours en mémoire. Comme xxx

que la longeon sera toujours en mémoire. JVM ne peut pas gc gc.

Dans cette situation, je pense que vous pouvez peut-être essayer xxx

comme code suivant xxx

Si vous courez avec -xmx60m, il sera de plus en plus de 6000+ et si vous utilisez la ligne 2 de code 2, commencez la ligne 1, puis il fonctionne longtemps plus grand que 6000


1 commentaires

Bonjour, bon point et merci. Je vérifierai le code pour voir si l'erreur existe



1
votes

Il est hautement improbable que toute utilisation réaliste de la scission "consommerait beaucoup de mémoire". Votre contribution devrait être énorme (beaucoup, beaucoup de mégaoctets) et votre résultat divisé en plusieurs millions em> de pièces pour cela pour même être remarqués.

Voici un code qui crée une chaîne aléatoire d'environ 1,8 Million de caractères et le divise en plus de 1 million de chaînes et génère la mémoire utilisée et la durée prise de temps. P>

Comme vous pouvez le constater, ce n'est pas beaucoup: 61 Mo consommé en seulement 350ms. P>

memory consumed due to split = 29582328


8 commentaires

J'utiliserais -xx: -usetlab pour une utilisation plus précise de la mémoire et déplacez le sb.tostring () à avant votre Démarrer fractionnement sur 60% des personnages est un peu fou. Que diriez-vous de [0-1] ?


Animal Hate: N'utilisez pas Stressbuffer, vous pouvez utiliser StringBuilder. ;)


@Peterlawrey merde! Je voulais utiliser stringbuilder . Et j'ai déplacé le Tostring () . Bit moins de mémoire utilisée par Split () . Séparateur sur tellement parce que je voulais créer un nombre fou d'objets de chaîne pour prouver Split () n'est pas le méchant.


Avez-vous essayé d'éteindre le TLAB? (Juste curieux) je voudrais aussi essayer system.gc () avant d'obtenir la mémoire utilisée pour ignorer les objets temporaires (OP semble être préoccupé par les objets conservés)


@Peterlawrey désactivant la mémoire réduite de TLAB utilisée à environ 25 Mo, cependant exécutant gc () La mémoire utilisée Leap à 71 Mo!


Essayez de faire la scission deux fois pour voir si elle échoue.


@Peterlawrey je devais utiliser xms = xmx pour arrêter de saisir plus et jeter les mesures de la mémoire, mais Split n ° 2 n'a utilisé que 9 Mo


Je soupçonne que 9 Mo est plus précis. ;)



0
votes

Vous devez utiliser une sorte de lecteur de flux et non pour abuser de la mémoire avec une grande chaîne de données. Voici quelques exemples: xxx


0 commentaires