Cuando es memoria, asignada por el proceso.NET, liberada de nuevo a Windows
garbage-collection memory-management (2)
Mi respuesta es que no importa. El sistema operativo proporciona a la aplicación (dentro de la cual se ejecuta el tiempo de ejecución .NET) memoria virtual . Esto no es memoria ''real''. El sistema operativo puede colocar cada página de la memoria virtual donde quiera, en el procesador, en la memoria principal, en el disco. Por lo tanto, es posible que una aplicación use más memoria que la cantidad de RAM en el sistema, y el sistema operativo copiará los bits que se necesitan a / desde el disco para garantizar que la aplicación se siga ejecutando (módulo de direccionamiento y limitaciones técnicas).
El sistema operativo administra la memoria virtual de todos los procesos en el sistema y garantiza que un programa no acapare toda la memoria RAM del sistema en detrimento de otros programas. Cuando el tiempo de ejecución de .NET solicita memoria del sistema para su uso en los montones, pero luego no la utiliza, esta memoria (si el sistema tiene poca RAM libre) se moverá al disco, porque no se puede acceder a ella. .
Aclaración vía correo electrónico de Tess : (énfasis mío)
Los tamaños de los segmentos se mantienen iguales a lo largo de la aplicación, pero hay dos cosas que considerar aquí.
Las asignaciones para un segmento es una asignación virtual , lo que significa que mientras reservamos memoria virtual , solo confirmamos lo que realmente usamos, por lo que los bytes privados utilizados para un segmento no son lo mismo que el tamaño del segmento, esto significa que después de un GC, sus bytes privados bajarán, mientras que sus bytes virtuales permanecerán igual.
Cuando ya no se usa un segmento, es decir, si le sucede a GC todo en un segmento para que ya no contenga ningún objeto .net, la asignación virtual se devuelve al sistema operativo.
Teniendo eso en cuenta, los segmentos del montón (mesas del restaurante) se devolverán al sistema operativo.
La puesta en marcha
.NET asigna memoria para el montón de cada generación (0, 1, 2, LOH) en segmentos para obtener un bloque continuo de memoria, en el inicio, y cuando intenta satisfacer una solicitud de asignación, después de una recopilación.
Esta memoria asignada para cada montón probablemente se nivelará a medida que la aplicación se caliente, excepto potencialmente para la generación 2 y el montón de objetos grandes. Durante una recolección de basura, cada montón (0, 1, 2) se barre y se compacta, excepto el montón de objetos grandes (LOH), que se acaba de barrer.
Entiendo que la parte de ''barrido'' de una colección significa que el GC identifica qué objetos ya no están enraizados y están disponibles para su recopilación (o finalización) y que ''compacto'' significa que las direcciones que aún están vivas en un montón se reorganizan de manera que que el montón restante disponible tiene más memoria continua disponible para él.
A medida que se excede el presupuesto para cada segmento dentro del montón, .NET asignará otro segmento para cumplir con las asignaciones si es posible.
La pregunta
Mi pregunta se reduce a lo que sucede con esa memoria en cada montón, que la aplicación ya no usa (confirma), pero ¿sigue siendo reservado por .NET? ¿Cuándo es lanzado de nuevo al sistema operativo? .
Creo que este es el escenario en el que puede parecer que un proceso consume mucha memoria (el tamaño virtual es bastante grande, pero los bytes privados son pequeños), pero cuando se inspeccionan sus montones, casi siempre hay espacio libre . Como otra advertencia, el tamaño total de los montones también puede ser bastante pequeño y no tener en cuenta la memoria que consume el proceso.
No hay un finalizador bloqueado y todo luce bien para un proceso: puede haber estado funcionando durante semanas antes de que se activara una alerta de monitor (por ejemplo).
Intentando obtener una mayor aclaración de la pregunta, si lee Tess .NET Memory Management - Una analogía del restaurante , si las tablas son segmentos del montón, ¿el restaurante alguna vez pierde las tablas (por ejemplo, segmentos del montón gratis)?
Editar
- Se eliminó la confusa referencia al set de trabajo y los pollos.
- Se agregó una referencia a la analogía del restaurante Tess.
No sé la respuesta a esto, pero sospecho que .NET no libera sus montones hasta que el proceso finaliza (y posiblemente en la descarga de un dominio de aplicación, en una suposición). Esto se basa únicamente en mi observación de los contadores de memoria .NET de perfmon. Los contadores de bytes totales de GC muestran, al menos en mi aplicación, que los bytes reservados suben y bajan un poco durante la vida útil de mi aplicación, como aproximadamente 30 MB.
Y, si el GC se está ejecutando en el modo de servidor, tal vez .NET libera la memoria con más frecuencia.