Pregunta

Me pregunto por qué no estoy en condiciones de asignar más de 1.000 MB de memoria en mi proceso de .NET de 32 bits. El siguiente mini-aplicación inicia una OutOfMemoryException después de haber asignado 1.000 MB. ¿Por qué 1000 MB, y no decir 1,8 GB? ¿Hay una configuración de todo el proceso que podría 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);
    }
}

PS: recogida de basura no ayuda

.

Editar, para aclarar lo que quiero: He escrito una aplicación de servidor que se ocupa de cantidades muy grandes de datos antes de escribir en la base de datos / disco. En lugar de crear archivos temporales de todo, he escrito una caché en memoria, lo que hace que todo sea súper rápido. Pero la memoria es limitada, y por lo que trató de averiguar cuáles son los límites. Y se preguntó por qué mi programa de prueba pequeña tiró la OutOfMemoryException después de exactamente 1.000 MB.

¿Fue útil?

Solución

El límite de espacio de dirección virtual de un proceso de Win32 es de 1,5 GB (no del todo cierto). Además, en los marcos de .NET hay un limitador para el% de memoria que un proceso puede consumir .NET. El machine.config tiene un elemento processModel con un atributo memoryLimit que es el% de memoria disponible un proceso puede consumir. El valor por defecto es 60%.

Si la máquina se está ejecutando en cuenta 2 GB de memoria o si no ha activado el modificador / 3GB en el archivo Boot.ini entonces usted va a obtener ~ 1,3 GB de memoria por proceso.

No puedo encontrar el artículo de KB, pero si no recuerdo mal 1.x NET no pueden abordar más allá del 1,5 GB (1,8 GB?) Limitar independientemente de la 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 / en-US / clr / hilo / c50ea343-B41B-467d-A457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_ -_Caching # Configure_the_Memory_Limit

Otros consejos

Tener enormes bloques de la memoria nunca es una buena idea, incluso en 64 bits. Se obtiene grandes problemas con la memoria contigua y la fragmentación.

El problema aquí es encontrar un bloque contiguo. Usted podría intentar activar el modo de 3GB (que podría ayudar a encontrar unos cuantos más bytes) pero realmente desaconsejarla. Las respuestas aquí son:

  • usar menos memoria
  • utilizar un sistema de base de datos / archivo
  • Uso x64

Es posible que también quiera leer Blog de Eric Lippert (parece que tiene una entrada de blog para cada pregunta .NET común ...)

Recientemente he estado haciendo extensa perfilado alrededor de los límites de memoria en .NET en un proceso de 32 bits. Todos nos bombardean con la idea de que podemos asignar hasta 2.4GB (2 ^ 31) en una aplicación .NET, pero por desgracia esto no es cierto :(. El proceso de solicitud tiene mucho espacio para utilizar el sistema operativo y hace un gran trabajo administrar por nosotros, sin embargo, .NET sí parece tener su propia cabeza que representa aproximadamente el 600-800MB para aplicaciones típicas del mundo real que empujan el límite de memoria. Esto significa que tan pronto como se asigna una matriz de enteros que toma alrededor de 1,4 GB, usted debe esperar ver un OutOfMemoryException ().

Obviamente en 64 bits, este límite se produce manera más tarde (vamos a charlar en 5 años :)), pero el tamaño general de todo en la memoria también crece (estoy encontrando es ~ 1,7 a ~ 2 veces) debido al aumento del tamaño de la palabra .

Lo que sé con certeza es que la idea de la memoria virtual del sistema operativo sin duda no le da espacio de asignación virtualmente sin fin dentro de un proceso. Es sólo allí para que el 2.4GB completo es direccionable a todas las aplicaciones (muchos) que se ejecutan al mismo tiempo.

Espero que esta visión un tanto ayuda.

Originalmente respondí algo relacionado aquí (todavía soy un Newby así que no estoy seguro de cómo se supone que tengo que hacer estos enlaces):

Es existe un límite de memoria para un solo proceso de .NET

Puede asignar mucha más memoria que ~ 2 GB mediante la construcción de su aplicación a una arquitectura de 64 bits, lo que requiere que se crea una nueva configuración de generación en Visual Studio, y que la acumulación de la aplicación sólo se ejecutará en 64 bits versiones de Windows. En .NET, utilizando el valor por defecto "Cualquier CPU" opción de construir para su aplicación, me parece que sólo soy capaz de asignar alrededor de 1,5 GB de memoria del montón (incluso en la máquina de Windows de 64 bits), que se debe a la aplicación en la práctica sólo se ejecuta en modo de 32 bits cuando se construye en el modo "Cualquier CPU". Sin embargo, mediante la compilación a la arquitectura x64, puede asignar mucho, mucho más memoria del montón durante la ejecución de la aplicación, y voy a explicar cómo crear un x64 construir para su aplicación a continuación:

Una vez más, el uso de la normal (por defecto) "Cualquier CPU" opción de construir en su proyecto .NET, su solicitud será siempre se ejecutan en el modo de 32 bits, incluso en un sistema operativo Windows de 64 bits. Por lo tanto usted no será capaz de asignar más de alrededor de 1,5 a 2 GB de memoria RAM durante la ejecución de la aplicación. Para ejecutar la aplicación .NET en modo verdadero de 64 bits, tendrá que entrar en el gestor de configuración de generación y crear un tipo de construcción para la arquitectura x64, y luego volver a compilar el programa para x64 usando explícitamente que el tipo de construcción. La opción del modo de acumulación 64 se puede crear para su solución .NET utilizando los siguientes pasos:

  1. En el Visual Studio "Explorador de soluciones" panel, haga clic derecho sobre el icono de la solución y elegir la opción "Gestor de configuración" en el menú emergente. Esto abrirá la acumulación de "Gestor de configuración" ventana de diálogo para el archivo de solución .NET.
  2. A la derecha, el lado superior de la construcción "Gestor de configuración" de diálogo, haga clic en la flecha hacia abajo y seleccione la opción "" opción. Esto abrirá el cuadro de diálogo "Nueva plataforma de soluciones".
  3. En el cuadro de diálogo "Nueva plataforma de soluciones", para la opción de "Plataforma", elegir la opción "x 64" en el menú desplegable. A continuación, haga clic en el botón "OK" y el nuevo, la opción de construir x64 ahora estará disponible en el cuadro de diálogo Administrador de configuración.
  4. A continuación, en el cuadro de diálogo "Gestor de configuración", seleccione "x 64" en el menú desplegable "plataforma de soluciones activas". El clic en el botón "Cerrar".
  5. En el Visual Studio "Explorador de soluciones" panel, haga clic derecho sobre el icono Proyecto CS y elija la opción "Propiedades" del 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 del proyecto CS, haga clic en la pestaña "Construir" para mostrar las propiedades de construcción para su proyecto de código. En la parte superior de esta ventana, se dio cuenta de que la "Plataforma" ahora debe decir "x 64" (en contraposición a los valores predeterminados "Cualquier CPU" opción). Si la "Plataforma" desplegable no muestra "x 64", debe seleccionar ahora.
  7. A continuación, sólo construir su código y en la carpeta "bin", ahora debería tener una carpeta x64 con la nueva construcción de 64 bits de su aplicación dentro de ella.

El uso de una acumulación de 64 bits de la aplicación en un 64 bits del sistema operativo Windows le permitirá a su programa para asignar mucho más que ~ 2 GB de memoria, presumiblemente hasta 2 ^ 64 espacios de direcciones (si tiene la memoria RAM y espacio en disco disponibles, que son los verdaderos factores limitantes como del momento de escribir esta respuesta).

Si usted todavía está quedando sin memoria en la aplicación, también puede aumentar el tamaño del archivo de paginación de memoria de Windows. En Windows, el archivo de página permite al sistema operativo para cambiar la memoria RAM en el disco, si se queda sin espacio de memoria RAM. Pero hay un costo a lo grande en el cambio de las secciones de la memoria RAM desde y hacia el disco, lo que puede ser un verdadero éxito en el rendimiento de la aplicación. Independientemente de los resultados, al aumentar el tamaño de la página, usted podría (en teoría) de hacer el archivo de página más grande que hay espacio libre disponible en la unidad C: de su máquina Windows. En ese caso, su aplicación sería capaz de asignar, por ejemplo, hasta 4 TBde la memoria (o cualquier cantidad de memoria que el tamaño de archivo de página está en) durante la ejecución de su programa. Para cambiar los ajustes del archivo de página para su máquina de Windows, haga lo siguiente:

  1. Abra el "Propiedades del sistema" de diálogo haciendo clic derecho sobre "Este PC" y seleccionando la opción "Propiedades" en el menú emergente. Esto se puede realizar también en versiones posteriores de Windows (Windows 10, Windows 2012 Server, etc ...), vaya 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 "Advanced System Properties". Esto mostrará la pestaña "Avanzado" del legado "Propiedades del sistema" de diálogo 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 paginación de memoria de Windows.
  5. Para aumentar el tamaño de archivo de página, haga clic en el botón "Cambiar" y se abrirá el cuadro de diálogo "memoria virtual".
  6. En el diálogo de "memoria virtual", seleccione la opción "C:", luego en "Tamaño personalizado", establecer los tamaños y "inicial" "máximos". Se puede utilizar cualquier tamaño hasta la cantidad máxima de espacio libre en la unidad C:, pero hacer este cambio que se reserva espacio para el archivo de paginación en el disco duro.
  7. A continuación, haga clic en "Aceptar" en todos los cuadros de diálogo para confirmar los nuevos ajustes. A continuación, reinicie el equipo para asegurarse que todos los cambios se han completado correctamente y que la nueva configuración del archivo de paginación están en funcionamiento.

De todos modos, espero que esto ayuda a la gente a entender por qué pueden encontrarse con este 1,5 - tema limitación de memoria de 2 GB en una aplicación .NET, incluso cuando se ejecutan en una máquina Windows de 64 bits. Esto puede ser un tema muy confuso para la gente y espero que mi explicación tiene sentido. Por favor, no dude en mensaje con preguntas sobre esta respuesta si es necesario.

Creo que el problema aquí es que esta aplicación será la adición de 10 MB con cada curva que describe, y el bucle es: "while (true)" lo que significa que la adición de estos 10Mbs hasta que se detiene la aplicación. Así que si se tratara de una duración de 100 bucle habría añadido cerca 1GBs a la RAM, y estoy suponiendo que hubiera hecho esto en menos de 30 segundos. Mi punto es que están tratando de 10 megabytes de memoria de por lazo, en un bucle sin fin

Lo siento de verdad si no lo consigo, pero su punto:

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 que utiliza? Y esto podría ser una pregunta estúpida, pero ¿por qué crear un bucle eterno? O si se intenta la tira de codificación de los símbolos>.> XD.

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

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