Question

Nous avons tendance la plupart du temps à suivre les meilleures pratiques ci-dessus.

Jetez un oeil à chaîne vs StringBuilder

Mais StringBuilder pourrait jeter OutOfMemoryException même quand il y a suffisamment de mémoire disponible . Il émet une exception OOM parce qu'il a besoin « bloc continu de la mémoire ».

Quelques liens pour référence StringBuilder OutOfMemoryException

et il y a beaucoup d'autres .....

Combien d'entre vous face à ce problème ou au courant et qu'avez-vous fait pour le résoudre?

Y at-il quelque chose que je suis absent?

P.S. Je ne connaissais pas cette

Je reformule la question.

*** La même chose a travaillé avec concaténation manuelle (je vais vérifier cela et mettre à jour SO). L'autre chose qui m'a causé préoccupation était qu'il ya suffisamment de mémoire dans le système. C'est la raison pour laquelle j'ai soulevé cette question ici pour vérifier si une face à ce problème ou il y avait quelque chose de radicalement faux avec le code.

Était-ce utile?

La solution

La chaîne que vous créez certain Sous-jacent également besoin d'un bloc contigu de mémoire car il est représenté comme un tableau de caractères (tableaux nécessitent de la mémoire contigus). Si le StringBuilder renvoie une exception OOM vous woludn't être en mesure de construire le sous-jacent sans elle.

Si la création d'une chaîne provoque une OOM, il y a probablement un problème plus grave dans votre application.

Modifier en réponse à la clarification:

Il y a un petit sous-ensemble de cas où la construction d'une chaîne avec un StringBuilder échouera lors concaténation manuelle réussit. concaténation manuel utilisera la longueur exacte nécessaire pour combiner deux chaînes tandis qu'un StringBuilder a un autre algorithmn pour l'allocation de mémoire. Il est plus agressif et sera probablement allouer plus de mémoire que est réellement nécessaire pour la chaîne.

L'utilisation d'un StringBuilder se traduira également par un doublement temporaire de la mémoire requise puisque la chaîne sera présente sous une forme System.String et StringBuilder simultanément pour un court laps de temps.

Mais si l'on voie est à l'origine d'un OOM et l'autre n'est pas, il reste des points susceptibles d'un problème plus grave dans votre programme.

Autres conseils

Si StringBuilder va jeter un OutOfMemoryException dans votre situation particulière, fait alors la concaténation de chaîne manuelle n'est pas une meilleure solution; il est bien pire. C'est exactement le cas (la création d'une chaîne extrêmement, extrêmement long) où StringBuilder est censé être utilisé. Manuel concaténation d'une chaîne cette grande prendra plusieurs fois la mémoire que la création d'une chaîne avec StringBuilder prendrait.

Cela dit, sur un ordinateur moderne, si votre chaîne est l'exécution de l'ordinateur de mémoire contigus votre conception est profondément, profondément erronée. Je ne peux pas imaginer ce que vous pourriez peut-être faire cela créerait une chaîne importante.

Combien de mémoire est-il question? Je ne parle pas de mémoire libre ou totale dans le système, mais combien de temps est la chaîne que vous êtes concaténer?

Une exception de débordement de la mémoire est presque toujours un très mauvais signe au sujet de votre code, même si elle échoue longtemps avant que la mémoire fonctionne réellement, comme vous avez vécu en raison de la mémoire non-disponibilité continue.

A ce moment-là, vous devez restructurer vraiment le code.

Par exemple, voici différentes façons de lutter contre le problème:

  1. Ne pas garder autant de données en mémoire à un moment donné, le mettre sur le disque ou quelque chose
  2. Break it up, tenir une liste des chaînes / stringbuilders et seulement les ajouter jusqu'à une certaine longueur avant de passer à une nouvelle, conserve le problème « mémoire continue » à distance
  3. Restructurer l'algorithme de ne pas construire gigaoctet de données en mémoire du tout

Si vous utilisez si près de votre mémoire limite que cela est encore une préoccupation, alors vous devriez probablement penser à une architecture différente ou d'obtenir une machine beefier.

Si vous regardez la façon dont est mise en œuvre StringBuilder, vous verrez qu'il utilise en fait un pour tenir les String données (méthodes internes a <=>, qui permettront de modifier en <=> place).

i.e.. ils utilisent la même quantité de mémoire. Toutefois, étant donné que se déploie automatiquement <=> le tableau sous-jacent et la copie si nécessaire en cas de besoin (mais doubler la capacité) qui est le plus probablement la cause de l'erreur de dépassement de mémoire. Mais comme d'autres l'ont déjà fait à la fois du besoin d'un bloc continu de mémoire,

Eh bien, la question est en fait, pourquoi avez-vous besoin de travailler avec des chaînes si longtemps? Si vous tombez sur ce problème, plus que probable que vous devez modifier votre concept.

Ce problème affecte même les System.String classe, vous devriez donc plutôt gros morceau de votre entrée dans et traiter les données en parallèle, ce qui devrait augmenter l'ensemble la performance si elle était écrite correctement.

Je rencontrais cette exception avec de très grandes chaînes construites sucessivement avec différentes stringbuilders (qui ne devrait pas avoir causé un problème car ils ont été déclarés dans les fonctions anonymes), et enfin résolu en réutilisant un StringBuilder, a déclaré à l'extérieur de la fonction anonyme.

J'ai eu une expérience très similaire où j'Annexer des cordes mais il a oublié d'ajouter le String.Format. Ainsi:

myStringBuilder.Append("1,""{0}""", someVeryLargeIntVariable)

aurait dû être:

myStringBuilder.Append(String.Format("1,""{0}""", someVeryLargeIntVariable))

Notez que ceci est mon code vb.net qui a échoué. Je répliqués un test similaire en C # avec:

myStringBuilder.Append('a', 1564544656);

vs.

myStringBuilder.Append(string.Format("1,\"{0}\"", 1564544656));

Mais dans mon cas, vb.net m'a en difficulté b / c des conversions implicites (je ne pouvais pas parallèle exactement même problème en C #).

J'espère que quelqu'un aide.

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