studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones .net memory-management

.net - para - manual de programacion android pdf



Memoria máxima que un proceso de.NET puede asignar (2)

¿Cuál es la memoria máxima que el recolector de basura puede asignar para un proceso .NET? Cuando compilo en x64, Process.GetCurrentProcess.MaxWorkingSet arroja unos 1,4 GB, pero cuando compilo AnyCPU (x64) se devuelve el mismo número. Para x64 debería ser más parecido al valor "Límite" que se muestra en el Administrador de tareas. ¿Cómo puedo obtener el número correcto que causará OutOfMemory-Exceptions cuando se supera en todos los casos?

Algunos ejemplos de lo que debe devolver el método:

1) Configuración de la máquina: x64-Windows, memoria física de 4GB, archivo de página de 4GB
-Como proceso de 64 bits: 8GB
-Como proceso de 32 bits: 1.4GB

2) Configuración de la máquina: x64-Windows, memoria física de 1GB, archivo de página de 2GB
-Como proceso de 64 bits: 3GB
-Como proceso de 32 bits: 1.4GB

3) Configuración de la máquina: x32-Windows, memoria física de 4GB, archivo de página de 4GB
-Como proceso de 64 bits: no sucederá
-Como proceso de 32 bits: 1.4GB

4) Configuración de la máquina: x32-Windows, 512 MB de memoria física, archivo de página de 512 MB
-Como proceso de 64 bits: no sucederá
-Como proceso de 32 bits: 1.0GB


¿No depende de la cantidad de RAM que tienes?

En teoría, un proceso x64 puede asignar EB''s (etabytes?) De RAM, creo, es decir, MUCHO. Pero si lo hace, su máquina debería comenzar a paginar como loca y generalmente morir.

Era diferente en el modo de 32 bits, ya que no se podía asignar más de 1 GB de RAM en CUALQUIER proceso en Windows (sí, hay formas de evitarlo, pero no es bonito). En la práctica, este precio de aproximadamente 7-800 meg por proceso .NET, como .NET reservó algo de espacio.

De cualquier forma, en 32 bits, lo máximo que puede usar es 3 GB: el sistema operativo reserva 1GB de espacio virtual para sí mismo.

En 64 bits, debería ser 2 ^ 64, que es un número grande, pero http://en.wikipedia.org/wiki/X86-64 dice que son 256TB de espacio virtual y 1TB de RAM REAL. De cualquier manera, es mucho más de lo que probablemente tenga en su máquina, por lo que llegará al archivo de la página.

Con un sistema operativo de 64 bits y un tiempo de ejecución de 64 bits, las aplicaciones basadas en .NET 2.0 ahora pueden utilizar 500 veces más memoria para datos tales como cachés basados ​​en servidores.

Esto también tiene buena información http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit

Por cierto, si está en una máquina x64 (es decir, máquina x64 + sistema operativo x64), compilar para AnyCPU y x64 hace lo mismo: se ejecuta en modo x64. La única diferencia es si usa AnyCPU vrs x86:

  • Aplicación x64 OS / .NET, AnyCpu: x64
  • x64 OS / .NET, x64: aplicación x64
  • x64 OS / .NET, x32: aplicación x32 (x64 .NET framework como AMBAS versiones x32 y x64 del Fx instaladas)

  • x32 OS / NET, AnyCPU: aplicación x32

  • x32 OS / .NET, x64: CRASH Y BURN BABY (en realidad, simplemente muere con gracia)
  • x32 OS / .NET, x32: x32 aplicación.

Windows se puede configurar para asignar más espacio de archivos de página bajo demanda o bajo pedido .
Los objetos de trabajo pueden evitar el consumo de más de una cierta cantidad de memoria.
Fragmentación del montón y naturaleza generacional del mismo (además de la necesidad de poner cosas grandes en el montón de objetos grandes)

Todo esto significa que el límite estricto no es muy útil en la realidad y significa que responder a la pregunta "¿cuánta memoria podría teóricamente asignar?" Es bastante más complejo de lo que crees.

Como es complejo, cualquiera que haga esa pregunta probablemente intente hacer algo mal y debería redirigir su pregunta a algo más útil.

¿Qué estás tratando de hacer que parece necesitar tal pregunta?

"Solo quiero saber cuándo la carga de memoria actual del proceso podría ser problemática para poder tomar medidas como liberar algunos elementos de un caché personalizado".

Derecha. esta es una pregunta mucho más tratable.

Dos soluciones en orden de complejidad:

  1. Haz que tus cachés utilicen WeakReferences
    • Esto significa que las cosas serán liberadas por el sistema casi mágicamente para usted, pero tendrá poco control sobre cosas como la política de reemplazo
    • esto se basa en que los datos en caché son mucho más grandes que la clave y la sobrecarga de una referencia débil
  2. Regístrese para recibir notificaciones de las colecciones de basura
    • Esto le permite tomar el control de liberar cosas.
    • usted confía en que el sistema tenga el tamaño máximo apropiado para las generaciones de GC, lo que puede tardar un tiempo en estabilizarse.

Puntos a tener en cuenta. ¿Es realmente menos costoso mantener esta caché masiva (ir al disco por el sonido de la misma) que volver a calcular / volver a solicitar los datos?
Si su caché exhibe una localidad pobre entre los elementos solicitados comúnmente / consecutivamente, entonces se gastará mucho esfuerzo en la búsqueda y extracción de datos. Una memoria caché más pequeña con una política de reajuste ajustada eficaz tiene buenas posibilidades de desempeñarse considerablemente mejor (y con un impacto mucho menor en otros programas en ejecución).

Como comentario aparte: en .Net, ningún objeto de tamaño variable (cadenas, matrices) puede tener más de 2 GB de tamaño debido a las limitaciones de las estructuras centrales de CLR para la administración de la memoria. (y cualquier solución anterior se beneficiará de esto)