see - ref summary c#
Asignar más de 1,000 MB de memoria en un proceso.NET de 32 bits (6)
Me pregunto por qué no puedo asignar más de 1,000 MB de memoria en mi proceso de .NET de 32 bits. La siguiente mini aplicación lanza una excepción OutOfMemoryException después de haber asignado 1,000 MB. ¿Por qué 1,000 MB, y no decir 1,8 GB? ¿Hay algún ajuste en el proceso que pueda cambiar?
static void Main(string[] args)
{
ArrayList list = new ArrayList();
int i = 0;
while (true)
{
list.Add(new byte[1024 * 1024 * 10]); // 10 MB
i += 10;
Console.WriteLine(i);
}
}
PD: la recolección de basura no ayuda.
Edite, para aclarar lo que quiero: he escrito una aplicación de servidor que trata con grandes cantidades de datos antes de escribir en la base de datos / disco. En lugar de crear archivos temporales para todo, he escrito un caché en memoria, lo que hace que todo sea súper rápido. Pero la memoria es limitada, y por eso traté de averiguar cuáles son los límites. Y me pregunté por qué mi pequeño programa de pruebas arrojó la excepción OutOfMemoryException después de exactamente 1,000 MB.
Creo que el problema aquí es que esta aplicación agregará 10 MB con cada bucle que haga, y el bucle es: "while (verdadero)", lo que significa que agregará estos 10 MB hasta que la aplicación se detenga. Entonces, si se ejecutara durante 100 bucles, se agregarían cerca de 1 GB a la RAM, y supongo que lo habría hecho en menos de 30 segundos. Mi punto es que estás tratando de 10 megabytes de memoria por bucle, en un bucle sin fin
El límite del espacio de direcciones virtuales de un proceso de Win32 es de 1.5 GB (no del todo cierto). Además, en los marcos .NET hay un limitador para el% de memoria que puede consumir un proceso .NET. El machine.config tiene un elemento processModel con un atributo memoryLimit que es el% de memoria disponible que puede consumir un proceso. El valor predeterminado es 60%.
Si la máquina en la que está ejecutando tiene 2GB de memoria o no ha habilitado el interruptor / 3GB en su BOOT.INI, entonces obtendrá ~ 1.3GB de memoria por proceso.
No puedo encontrar el artículo de KB, pero si recuerdo correctamente .NET 1.x no puedo abordar más allá del límite de 1.5GB (1.8GB?), Independientemente de su configuración.
http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_-_Caching#Configure_the_Memory_Limit
Lo siento mucho si no entendí tu punto, pero:
static void Main(string[] args)
{
ArrayList list = new ArrayList();
int i = 0;
while (true)
{
using(byte newBt = new byte[1024 * 1024 * 10])
{
list.Add(newBt); // 10 MB
i += 10;
Console.WriteLine(i);
}
}
}
¿Has probado el método de uso? Y esta podría ser una pregunta estúpida, pero ¿por qué creaste un ciclo eterno? O si intentas el código, quita los símbolos>.> XD.
Fuente: http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx
Puede asignar MUCHO MÁS memoria que ~ 2 GB construyendo su aplicación a una arquitectura de 64 bits, lo que requiere que cree una nueva configuración de compilación en Visual Studio, y esa compilación de la aplicación solo se ejecutará en versiones de Windows de 64 bits. . En .NET, al usar la opción de compilación predeterminada "Cualquier CPU" para su aplicación, encuentro que solo puedo asignar alrededor de 1.5 GB de memoria del montón (incluso en una máquina Windows de 64 bits), lo cual se debe a que la aplicación realmente solo se ejecuta en modo de 32 bits cuando está integrado en el modo "Cualquier CPU". Pero al compilar a la arquitectura x64, puede asignar mucha, mucha más memoria del montón durante la ejecución de su aplicación, y explicaré cómo crear una compilación x64 para su aplicación a continuación:
Nuevamente, al utilizar la opción de compilación "Cualquier CPU" normal (predeterminada) en su proyecto .NET, su aplicación SIEMPRE se ejecutará en modo de 32 bits, incluso en un sistema operativo Windows de 64 bits. Por lo tanto, no podrá asignar más de aproximadamente 1,5 a 2 GB de memoria RAM durante la ejecución de la aplicación. Para ejecutar su aplicación .NET en modo verdadero de 64 bits, deberá ingresar al administrador de configuración de compilación y crear un tipo de compilación para la arquitectura x64, y luego volver a compilar su programa para x64 explícitamente usando ese tipo de compilación. La opción de modo de compilación x64 se puede crear para su solución .NET mediante los siguientes pasos:
- En el panel "Explorador de soluciones" de Visual Studio, haga clic con el botón derecho en el icono de Solución y elija la opción "Administrador de configuración" en el menú emergente. Esto abrirá la ventana de diálogo "Administrador de configuración" de compilación para el archivo de solución .NET.
- En la parte superior derecha del cuadro de diálogo "Administrador de configuración", haga clic en la flecha hacia abajo y seleccione la opción "<nuevo>". Esto abrirá el cuadro de diálogo "Nueva plataforma de soluciones".
- En el cuadro de diálogo "Nueva plataforma de soluciones", para la opción "Plataforma", seleccione "x64" en el menú desplegable. Luego haga clic en el botón "Aceptar" y la nueva opción de compilación x64 ahora estará disponible en el cuadro de diálogo Administrador de configuración.
- Luego, en el cuadro de diálogo "Administrador de configuración", seleccione "x64" en el menú desplegable "Plataforma de solución activa". El clic en el botón "Cerrar".
- En el panel "Explorador de soluciones" de Visual Studio, haga clic con el botón derecho en el icono de CS Project y elija la opción "Propiedades" en el menú emergente (la última opción en la parte inferior de este menú). Esto abrirá la ventana de propiedades del Proyecto CS.
- En el lado izquierdo de la ventana de propiedades del Proyecto CS, haga clic en la pestaña "Crear" para mostrar las propiedades de construcción para su proyecto de código. En la parte superior de esta ventana, observe que la "Plataforma" ahora debería decir "x64" (a diferencia de la opción predeterminada "Cualquier CPU"). Si el menú desplegable "Plataforma" no muestra "x64", debe seleccionarlo ahora.
- Luego simplemente compile su código y en la carpeta "bin", ahora debería tener una carpeta x64 con la nueva compilación de 64 bits de su aplicación dentro de ella.
El uso de una compilación de 64 bits de su aplicación en un sistema operativo Windows de 64 bits le permitirá a su programa asignar mucho más que ~ 2 GB de memoria, probablemente hasta 2 ^ 64 espacios de direcciones (si tiene la RAM y el espacio de disco disponible, lo que son los factores limitantes reales en el momento de escribir esta respuesta).
Si TODAVÍA se está quedando sin memoria en su aplicación, también puede aumentar el tamaño del archivo de la página de memoria de Windows. En Windows, el archivo de la página permite que el sistema operativo cambie la memoria de la RAM al disco, si se queda sin espacio en la memoria RAM. Pero hay un gran costo de tiempo al cambiar las secciones de la memoria RAM hacia y desde el disco, por lo que puede ser un verdadero golpe en el rendimiento de su aplicación. Independientemente del rendimiento, al aumentar el tamaño de la página, podría (en teoría) hacer que el archivo de la página sea tan grande como haya espacio libre disponible en la unidad C: de su máquina Windows. En ese caso, su aplicación podría asignar, por ejemplo, hasta 4 TB de memoria (o la cantidad de memoria en la que esté configurado el tamaño del archivo de su página) durante la ejecución de su programa. Para cambiar la configuración del archivo de página para su máquina Windows, haga lo siguiente:
- Abra el cuadro de diálogo "Propiedades del sistema" haciendo clic derecho en "Esta PC" y seleccionando la opción "Propiedades" en el menú emergente. Esto también se puede lograr en versiones posteriores de Windows (Windows 10, Win 2012 Server, etc.) yendo a "Inicio"> "Panel de control"> "Sistema y seguridad"> "Sistema".
- En el lado izquierdo del cuadro de diálogo "Sistema", haga clic en la opción "Propiedades avanzadas del sistema". Esto mostrará la pestaña "Avanzada" del diálogo heredado "Propiedades del sistema" para Windows.
- En la pestaña "Opciones avanzadas" del cuadro de diálogo "Propiedades del sistema", haga clic en el botón "Configuración" en el cuadro "Rendimiento". Esto abrirá el cuadro de diálogo "Opciones de rendimiento".
- En el cuadro de diálogo "Opciones de rendimiento", haga clic en la pestaña "Avanzadas" para ver la configuración de tamaño actual del archivo de la página de memoria de Windows.
- Para aumentar el tamaño del archivo de la página, haga clic en el botón "Cambiar" y se abrirá el cuadro de diálogo "Memoria virtual".
- En el cuadro de diálogo "Memoria virtual", seleccione la unidad "C:", luego en "Tamaño personalizado", configure los tamaños "Inicial" y "Máximo". Puede usar cualquier tamaño hasta la cantidad máxima de espacio libre en la unidad C :, pero al hacer este cambio se reservará ese espacio para el archivo de la página en el disco duro.
- Luego haga clic en "Aceptar" en todos los cuadros de diálogo para confirmar la nueva configuración. Luego reinicie su computadora para asegurarse de que todos los cambios se hayan completado correctamente y que la nueva configuración del archivo de página esté en funcionamiento.
De todos modos, espero que esto ayude a la gente a comprender por qué pueden encontrarse con este problema de limitación de memoria de 1.5 - 2 GB en una aplicación .NET, incluso cuando se ejecuta en una máquina Windows de 64 bits. Esto puede ser un tema muy confuso para las personas y espero que mi explicación tenga sentido. Por favor, no dude en enviarme un mensaje con preguntas sobre esta respuesta si es necesario.
Recientemente he estado realizando un amplio análisis de los límites de memoria en .NET en un proceso de 32 bits. Todos nos vemos bombardeados por la idea de que podemos asignar hasta 2.4GB (2 ^ 31) en una aplicación .NET, pero desafortunadamente esto no es cierto :(. El proceso de la aplicación tiene mucho espacio para usar y el sistema operativo hace un gran trabajo. sin embargo, el propio .NET parece tener su propia sobrecarga que representa aproximadamente 600-800MB para las aplicaciones típicas del mundo real que aumentan el límite de la memoria. Esto significa que tan pronto como asigna una matriz de enteros que requiere aproximadamente 1.4 GB, debe esperar ver una excepción OutOfMemoryException ().
Obviamente, en 64 bits, este límite ocurre mucho más tarde (hablemos en 5 años :)), pero el tamaño general de todo lo que hay en la memoria también crece (me parece que es ~ 1.7 a ~ 2 veces) debido al aumento en el tamaño de las palabras.
Lo que sé con certeza es que la idea de memoria virtual del sistema operativo definitivamente NO le otorga un espacio de asignación virtualmente infinito dentro de un proceso. Solo está allí para que los 2.4GB completos sean direccionables a todas las (muchas) aplicaciones que se ejecutan al mismo tiempo.
Espero que esta idea ayude un poco.
Originalmente respondí algo relacionado aquí (todavía soy un novato, así que no estoy seguro de cómo debo hacer estos enlaces):
Tener enormes bloques de memoria nunca es una buena idea, incluso en 64 bits. Tienes grandes problemas con la memoria contigua y la fragmentación.
El problema aquí es encontrar un bloque contiguo. Podrías intentar habilitar el modo 3gb (lo que podría ayudarlo a encontrar algunos bytes más), pero realmente desaconsejo. Las respuestas aquí son:
- usa menos memoria
- usar una base de datos / sistema de archivos
- usar x64
También es posible que desee leer el blog de Eric Lippert (parece que tiene una entrada de blog para todas las preguntas comunes de .NET ...)