Asignación de más de 1,000 MB de memoria en el proceso .NET de 32 bits

Me pregunto por qué no puedo asignar más de 1.000 MB de memoria en mi proceso .NET de 32 bits. La siguiente mini aplicación arroja una OutOfMemoryException después de haber asignado 1,000 MB. ¿Por qué 1.000 MB, y no digamos 1.8 GB? ¿Hay algún ajuste en todo 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: Recolectar basura no ayuda.

Editar, 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 superrápido. Pero la memoria es limitada, así que traté de averiguar cuáles son los límites. Y me pregunté por qué mi pequeño progtwig de prueba arrojó OutOfMemoryException después de exactamente 1,000 MB.

    El límite de espacio de direcciones virtuales de un proceso de Win32 es de 1.5 GB (no del todo cierto). Además, en los frameworks .NET hay un limitador al% de memoria que un proceso .NET puede consumir. Machine.config tiene un elemento processModel con un atributo memoryLimit que es el% de memoria disponible que un proceso puede consumir. El valor predeterminado es 60%.

    Si la máquina 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 puede resolver 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 / Foros / es-ES / clr / thread / c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_-_Caching#Configure_the_Memory_Limit

    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ía intentar habilitar el modo 3gb (lo que podría ayudarlo a encontrar algunos bytes más), pero realmente desaconsejo hacerlo. Las respuestas aquí son:

    • usa menos memoria
    • utilizar una base de datos / sistema de archivos
    • usa x64

    También puede leer el blog de Eric Lippert (parece tener una entrada de blog para cada pregunta .NET común …)

    Recientemente he estado haciendo un amplio perfil sobre los límites de memoria en .NET en un proceso de 32 bits. Todos nos sentimos bombardeados por la idea de que podemos asignar hasta 2,4 GB (2 ^ 31) en una aplicación .NET, pero lamentablemente esto no es cierto :(. El proceso de solicitud tiene mucho espacio para usar y el sistema operativo funciona muy bien. Sin embargo, el propio .NET parece tener su propia sobrecarga, que representa aproximadamente 600-800MB para aplicaciones típicas del mundo real que superan el límite de memoria. Esto significa que tan pronto como se asigna una matriz de enteros que toma aproximadamente 1,4 GB, debe esperar ver OutOfMemoryException ().

    Obviamente en 64 bits, este límite se produce mucho más tarde (chateemos en 5 años :)), pero el tamaño general de todo en la memoria también crece (me parece que es ~ 1.7 a ~ 2 veces) debido al aumento del tamaño de la palabra.

    Lo que sí sé con certeza es que la idea de Memoria Virtual del sistema operativo definitivamente NO le da un espacio de asignación prácticamente infinito dentro de un proceso. Está solo allí, por lo que los 2.4 GB completos son direccionables para todas las (muchas) aplicaciones que se ejecutan a la vez.

    Espero que esta idea sea de alguna ayuda.

    Originalmente respondí algo relacionado aquí (todavía soy un recién llegado, así que no estoy seguro de cómo se supone que debo hacer estos enlaces):

    ¿Hay un límite de memoria para un solo proceso .NET?

    Puede asignar MUCHA MÁS memoria que ~ 2 GB creando su aplicación en una architecture de 64 bits, lo que requiere que cree una nueva configuración de comstackción en Visual Studio, y esa comstackción de la aplicación solo se ejecutará en versiones de 64 bits de Windows . En .NET, usando la opción de comstackción predeterminada “Cualquier CPU” para su aplicación, descubro que solo puedo asignar alrededor de 1,5 GB de memoria del montón (incluso en una máquina con Windows de 64 bits), lo cual se debe a que la aplicación en realidad solo se ejecuta en modo de 32 bits cuando está construido en el modo “Cualquier CPU”. Pero comstackndo a la architecture x64, puede asignar mucha, mucha más memoria del montón durante la ejecución de su aplicación, y le explicaré cómo crear una comstackción x64 para su aplicación a continuación:

    De nuevo, usando la opción de comstackción normal (predeterminada) “Cualquier CPU” 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 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á acceder al administrador de configuración de comstackción y crear un tipo de comstackción para la architecture x64, y luego recomstackr su progtwig para x64 de forma explícita utilizando ese tipo de comstackción. La opción del modo de construcción x64 se puede crear para su solución .NET mediante los siguientes pasos:

    1. En el panel “Explorador de soluciones” de Visual Studio, haga clic con el botón derecho en el icono de Solución y seleccione la opción “Administrador de configuración” en el menú emergente. Esto abrirá la ventana de diálogo “Administrador de configuración” para el archivo .NET Solution.
    2. 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 ““. Esto abrirá el cuadro de diálogo “Nueva plataforma de solución”.
    3. En el cuadro de diálogo “Plataforma de nueva solución”, para la opción “Plataforma”, elija “x64” en el menú desplegable. A continuación, haga clic en el botón “Aceptar” y la nueva opción de comstackción x64 estará disponible en el cuadro de diálogo Administrador de configuración.
    4. Luego, en el cuadro de diálogo “Administrador de configuración”, seleccione “x64” en el menú desplegable “Plataforma de solución activa”. Haga clic en el botón “Cerrar”.
    5. En el panel “Explorador de soluciones” de Visual Studio, haga clic con el botón derecho en el icono de CS Project y seleccione 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.
    6. En el lado izquierdo de la ventana de propiedades de CS Project, 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” debería decir ahora “x64” (en oposición a la opción predeterminada “Cualquier CPU”). Si el menú desplegable “Plataforma” no muestra “x64”, debe seleccionarlo ahora.
    7. Luego, simplemente crea tu código y en la carpeta “bin”, ahora deberías tener una carpeta x64 con la nueva comstackción de 64 bits de tu aplicación dentro de ella.

    El uso de una comstackción de 64 bits de su aplicación en un sistema operativo Windows de 64 bits permitirá que su progtwig asigne mucho más de ~ 2GB de memoria, presumiblemente hasta 2 ^ 64 espacios de direcciones (si tiene la RAM y el espacio disponible en el disco, son los verdaderos factores limitantes al momento de escribir esta respuesta).

    Si aún se está quedando sin memoria en su aplicación, también puede boost el tamaño del archivo de la página de memoria de Windows. En Windows, el archivo de página permite que el sistema operativo cambie la memoria de la RAM al disco, si se queda sin memoria RAM. Pero hay un gran costo de tiempo en el cambio de 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 boost el tamaño de la página, podría (en teoría) hacer que el archivo de la página sea tan grande como que 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 que tenga configurado el tamaño de su archivo de página) durante la ejecución de su progtwig. Para cambiar la configuración del archivo de página para su máquina con Windows, haga lo siguiente:

    1. 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”.
    2. 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 “Avanzado” del diálogo heredado de “Propiedades del sistema” para Windows.
    3. En la pestaña “Avanzado” 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”.
    4. En el cuadro de diálogo “Opciones de rendimiento”, haga clic en la pestaña “Avanzado” para ver la configuración de tamaño actual para el archivo de la página de memoria de Windows.
    5. Para boost el tamaño del archivo de página, haga clic en el botón “Cambiar” y se abrirá el cuadro de diálogo “Memoria virtual”.
    6. 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 página en el disco duro.
    7. A continuación, 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 de que la nueva configuración del archivo de la página esté en funcionamiento.

    De todos modos, espero que esto ayude a las personas a entender por qué pueden toparse con este problema de limitación de memoria de 1.5 a 2 GB en una aplicación .NET, incluso cuando se ejecuta en una máquina con Windows de 64 bits. Esto puede ser un tema muy confuso para las personas y espero que mi explicación tenga sentido. Si es necesario, siéntase libre de enviarme un mensaje con preguntas sobre esta respuesta.

    Creo que el problema aquí es que esta aplicación agregará 10MB con cada ciclo que haga, y el ciclo es: “while (true)”, lo que significa que agregará estos 10MB hasta que la aplicación se detenga. Entonces, si se ejecutara en 100 bucles, habría agregado cerca de 1GB a la RAM, y supongo que lo habría hecho en menos de 30 segundos. Mi punto es que estás intentando obtener 10 megabytes de memoria por ciclo, en un ciclo interminable

    Realmente lo siento 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 prueba el código, quite los símbolos>.> XD.

    Fuente: http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx