Una de las razones por las que su sistema podría detenerse es porque el código de .NET se ejecuta más cerca del metal y está en un circuito cerrado que debe consumir 100% de CPU siempre que la prioridad del proceso lo permita. Si desea evitar que la aplicación consuma demasiada CPU mientras realiza el ciclo cerrado, debe agregar algo como System.Threading.Thread.Sleep(10) al final del ciclo, lo que forzará el tiempo de procesamiento de otros hilos.
Una diferencia importante entre el CLR de JVM y .NET (Common Language Runtime) es que CLR no limita el tamaño de su memoria en un sistema/aplicación x64 (en aplicaciones de 32 bits, sin el indicador de dirección grande el sistema operativo limita cualquier aplicación a 2GB debido a limitaciones de direccionamiento). El compilador JIT crea código nativo de Windows para su arquitectura de procesamiento y luego lo ejecuta en el mismo ámbito que cualquier otra aplicación de Windows. La JVM es una zona de pruebas más aislada que limita la aplicación a un tamaño específico dependiendo de los parámetros de configuración/línea de comandos.
En cuanto a las diferencias entre los dos algoritmos:
La creación cuerda suelta no está garantizada a fallar cuando se ejecuta en un entorno de 64 bits con suficiente memoria contigua para asignar el 4 GB necesario contener caracteres int.MaxValue (cadenas .NET son Unicode por defecto, lo que requiere 2 bytes por carácter). Una aplicación de 32 bits siempre fallará, incluso con la bandera Large Address Aware configurada porque la memoria máxima es todavía algo así como 3.5GB.
La versión de ciclo While de su código probablemente consumirá más memoria total, siempre que tenga suficiente disponible, antes de lanzar la excepción porque las cadenas se pueden asignar en fragmentos más pequeños, pero se garantiza que llegue al error (aunque tiene muchos recursos, podría suceder como resultado de que ArrayList excediera la cantidad máxima de elementos en una matriz en lugar de la incapacidad de asignar espacio nuevo para una cadena pequeña). Kent Murra también tiene razón sobre el interrogatorio de cuerdas; necesitará aleatorizar la longitud de la cadena o el contenido de los caracteres para evitar la internación, de lo contrario, simplemente está creando punteros a la misma cadena. La recomendación de Steve Townsend de aumentar la longitud de la cuerda también dificultaría la búsqueda de bloques contiguos de memoria lo suficientemente grandes, lo que permitirá que la excepción ocurra más rápidamente.
EDIT:
pensé que le daría algunos enlaces personas les puede resultar útil para la comprensión de la memoria .NET:
Estos dos artículos son un poco más viejo, pero muy bueno en la profundidad de lectura:
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
Garbage Collection Part 2: Automatic Memory Management in the Microsoft .NET Framework
Estos son los blogs de una colección de basura desarrollar .NET er para obtener información sobre la versión más reciente de gestión de memoria .NET:
So, what’s new in the CLR 4.0 GC?
CLR 4.5: Maoni Stephens - Server Background GC
Este SO pregunta puede ayudarle a observar el funcionamiento interno de.NET memoria:
.NET Memory Profiling Tools
¿Qué hace el segundo? – SLaks
segundo jst sigue funcionando hasta que mi máquina no responde y tengo que arrancarlo duro – ksm
Puede valer la pena señalar para futuros visitantes de esta publicación que .net 4.5 elimina esta limitación si la estoy leyendo correctamente. http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx – TravisWhidden