Pregunta

En su mayoría, tendemos a seguir las mejores prácticas anteriores.

Mira esto Cadena vs StringBuilder

Pero StringBuilder podría lanzar OutOfMemoryException incluso cuando hay suficiente memoria disponible.Lanza una excepción OOM porque necesita un "bloque continuo de memoria".

Algunos enlaces para referencia.StringBuilder OutOfMemoryException

Y hay muchos más.....

¿Cuántos de ustedes enfrentaron este problema o fueron conscientes y qué hicieron para resolverlo?

¿Hay algo que me falta?

PD:No estaba al tanto de esto.

He reformulado la pregunta.

*** Lo mismo funcionó con la concatenación manual (verificaré esto y actualizaré SO).La otra cosa que me preocupó fue que hay suficiente memoria en el sistema.Esa es la razón por la que planteé esta pregunta aquí para verificar si alguien enfrentó este problema o si había algo drásticamente mal con el código.

¿Fue útil?

Solución

La cadena underyling se crea también necesitará un bloque contiguo de memoria, ya que se representa como una serie de caracteres (arrays requieren memoria contigua). Si el StringBuilder una excepción OOM que woludn't será capaz de construir el subyacente sin él.

Si la creación de una cadena causa un OOM, es posible que haya un problema más grave en su aplicación.

Editar en respuesta a aclaración:

Hay un pequeño subconjunto de los casos en que la construcción de una cadena con un StringBuilder fallará cuando concatenación manual de éxito. concatenación manual utilizará la longitud exacta requerida con el fin de combinar dos cadenas mientras que un StringBuilder tiene una algorithmn diferente para la asignación de memoria. Es más agresivo y es probable que asignar más memoria de la que realmente se necesita para la cadena.

Uso de un StringBuilder también dará lugar a una duplicación temporal de la memoria necesaria ya que la cadena estará presente en una forma System.String y StringBuilder simultáneamente por un corto tiempo.

Pero si una forma es haciendo un OOM y el otro no lo es, puntos siendo probable que un problema más grave en su programa.

Otros consejos

Si StringBuilder va a lanzar una OutOfMemoryException en su situación particular, a continuación, haciendo la concatenación de cadenas manual no es una solución mejor; es mucho peor. Este es exactamente el caso (la creación de una cadena muy, muy largo) donde se supone que StringBuilder para ser utilizado. concatenación manual de una soga tan grande va a tomar muchas veces la memoria que la creación de una cadena con StringBuilder tomaría.

Dicho esto, en un equipo moderno, si su secuencia es que ejecuta el equipo de memoria contigua su diseño es profundamente, profundamente defectuoso. No me puedo imaginar lo que posiblemente podría hacer que crearía una cadena tan grande.

¿Cuánta memoria estamos hablando? No estoy hablando de memoria libre o total en el sistema, pero ¿cuánto tiempo es la cadena que está concatenando?

A excepción de desbordamiento de memoria es casi siempre una mala señal sobre su código, incluso si no mucho antes de que la memoria se agota en realidad, al igual que ha experimentado debido a la memoria continua no estar disponible.

En ese momento realmente debería reestructurar el código.

Por ejemplo, aquí hay varias maneras de combatir el problema:

  1. No mantener la mayor cantidad de datos en la memoria a la vez, lo puso en el disco o algo
  2. Dividirla, mantener una lista de cuerda / stringbuilders y sólo añadir a ellos hasta una cierta longitud antes de cambiar a una nueva, mantiene el problema de la "memoria continua" a raya
  3. Reestructurar el algoritmo para que no se acumule gigabyte de datos en la memoria en absoluto

Si está ejecutando tan cerca de su memoria límites que esto es aún una preocupación, entonces probablemente debe pensar en una arquitectura diferente o conseguir una máquina más robusto.

Si nos fijamos en cómo se implementa StringBuilder, verá que en realidad se utiliza una String para contener los datos (<=> tiene métodos internos, que permitirán <=> modificar en su lugar).

es decir. ambos utilizan la misma cantidad de memoria. Sin embargo, puesto <=> se extenderá automáticamente la matriz subyacente y de la copia según sea necesario cuando sea necesario (pero doblando la capacidad) que es más probable la causa del error de falta de memoria. Pero como ya se ha señalado, tanto del requerir un bloque continuo de memoria,

Bueno, la pregunta realmente es, ¿por qué necesita para trabajar con cadenas tanto tiempo? Si te topas con este problema, lo más probable es que usted debe alterar su concepto.

Este problema afecta incluso el System.String clase, por lo que debe más bien trozo de su entrada en y procesar los datos en paralelo, lo que debería incrementar general rendimiento si escrito correctamente.

Me encontré con esta excepción, con muy grandes cadenas construidas sucessively con diferentes stringbuilders (que no debe haber causado un problema ya que se declaran dentro de funciones anónimas), y finalmente lo resolvió mediante la reutilización de un solo StringBuilder, declarado fuera de la función anónima.

Tuve una experiencia muy similar en la que estaba agregando cadenas pero olvidé agregar String.Format.De este modo:

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

debería haber sido:

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

Tenga en cuenta que este es mi código vb.net que falló.Repliqué una prueba similar en C# con:

myStringBuilder.Append('a', 1564544656);

vs.

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

Pero en mi caso, vb.net me metió en problemas debido a las conversiones implícitas (no podía comparar el exacto mismo problema en c#).

Espero que ayude a alguien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top