¿Qué representa el «uso de memoria» de Windows? — Cómo leer Working Set, Private Bytes, Commit y el archivo de paginación
· Actualizado el: · Go Komura · Windows, Desarrollo en Windows, Gestión de memoria, Working Set, Private Bytes, Commit, Archivo de paginación, Supervisión del rendimiento, Investigación de fallos, Sysinternals
Historial de revisiones (primera versión, publicada el 4 Aug 2026)
- Primera publicación
Citar este artículo(DOI (archivo registrado): 10.5281/zenodo.22175960)
Los DOI siguientes remiten a versiones ya archivadas y pueden diferir del texto actual. Para citar el texto actual, utilice la URL de esta página.
Go Komura (2026). ¿Qué representa el «uso de memoria» de Windows? — Cómo leer Working Set, Private Bytes, Commit y el archivo de paginación. KomuraSoft LLC. https://comcomponent.com/es/blog/windows-memory-usage-working-set-commit/
- DOI (archivo registrado)
- 10.5281/zenodo.22175960
- DOI (última versión registrada)
- 10.5281/zenodo.22175961
En el Administrador de tareas, la «Memoria» de un proceso aparece como 1,2 GB. Sin embargo, en Process Explorer el Working Set es 1,5 GB, Private Bytes es 2,4 GB, y en VMMap el Size es todavía mayor. Al mirar todo el sistema, se muestra «Comprometido 19,6/31,8 GB».
Entonces, ¿cuántos GB de memoria está usando realmente esta aplicación?
La diferencia entre estos números, por sí sola, no permite concluir que alguno esté equivocado. El indicador que hay que mirar cambia según lo que se quiera saber.
La cantidad que está ahora en RAM, la cantidad asignada de forma propia a ese proceso, la cantidad que el sistema promete seguir sosteniendo en el futuro y el rango de direcciones virtuales reservado son cosas distintas. Antes de preguntar «¿cuántos GB?», conviene establecer «¿cantidad de qué?».
Los indicadores de memoria de Windows resultan difíciles porque todos se muestran bajo la misma palabra, «memoria», aunque en realidad miden los siguientes ejes distintos.
- Cuánto espacio de direcciones se está usando
- Cuánto Commit se está consumiendo
- Si está residente en la RAM física en este momento
- Si esa página es propia del proceso o puede compartirse
- Cuánta asignación adicional puede sostener todo el sistema
Este artículo está dirigido a quienes investigan el crecimiento de memoria de una aplicación o la falta de memoria de todo el sistema en Windows 10/11 y en las versiones actuales de Windows Server, y conecta en un solo esquema la relación entre Working Set, Private Working Set, Private Bytes, Commit, Virtual Bytes, el archivo de paginación, Available y los Page Fault.
El procedimiento para rastrear por qué no se liberan objetos de .NET se trata en detalle en «Cómo distinguir la espera de GC de una fuga de memoria en .NET», y el manejo concreto de VMMap y Process Explorer se trata en «Process Explorer / Handle / VMMap en la práctica». Este artículo se centra en la base de todo eso: cómo leer los números del lado del sistema operativo Windows.
1. Primero, la conclusión
Working Set es «la cantidad que está ahora en RAM», Private Bytes es «la cantidad prometida de forma propia a este proceso» y System Commit es «la cantidad que todo el sistema ha prometido». Empiece por leer estos tres por separado.
Alinear cada indicador con la pregunta que responde
| Lo que se quiere saber | Indicador a mirar | Precaución al leerlo |
|---|---|---|
| Cuánto del proceso objetivo está ahora en RAM | Working Set | Incluye no solo las páginas propias del proceso, sino también páginas compartidas como el código de DLL o archivos mapeados en memoria1 |
| De eso, cuánta RAM usa solo ese proceso | Private Working Set | Es una aproximación de «la RAM que este proceso ocupa en exclusiva ahora mismo», no el total que la aplicación ha reservado2 |
| Cuánto Commit es propio del proceso objetivo | Private Bytes | No depende de si las páginas están residentes en RAM. Tampoco es el número de bytes realmente escritos en el archivo de paginación2 |
| Si el Commit de todo el sistema tiene margen | «Comprometido X/Y» | X es la cantidad actual, Y es el límite. X no es el uso del archivo de paginación, e Y se determina, a grandes rasgos, por la suma de la RAM y el archivo de paginación3 |
Preste también atención al nombre PagefileUsage de la API Win32. En las versiones actuales de Windows representa, en la práctica, el mismo Commit Charge que Private Bytes, y no la cantidad realmente escrita en el archivo de paginación.2
No juzgar solo porque «se reservó» o «aumentó»
Si un rango de direcciones virtuales solo se ha reservado (Reserve), únicamente se ha apartado para usarlo en el futuro. No consume la misma cantidad de RAM ni de límite de Commit; Reserve y Commit son etapas distintas.45
Además, un Page Fault no es necesariamente E/S de disco. Hay que distinguir los fallos blandos, que se resuelven dentro de la RAM, de los fallos duros, que leen desde el archivo de paginación, un ejecutable, un archivo mapeado en memoria u otros orígenes similares.16
Una fuga de memoria tampoco se juzga con un solo valor grande. Hay que ver si, al repetir la misma carga, Private Bytes o su desglose siguen subiendo por escalones después de cada ejecución, en lugar de volver al mismo estado estable. Lo que se mira no es el tamaño en un instante, sino el suelo y la pendiente después de repetir.
Leer según el síntoma o el objetivo
| Lo que está ocurriendo ahora | Dónde leer |
|---|---|
| Los números no coinciden entre herramientas y no se sabe cuál mirar | Capítulo 2: Los cuatro ejes que separan los indicadores, Capítulo 9: Cómo elegir pantallas y herramientas |
| Hay OutOfMemory aunque quede RAM libre | 3.4: Restricciones de asignación distintas de la RAM, Capítulo 6: El límite de Commit de todo el sistema |
| Working Set o Private Bytes no dejan de crecer | Capítulo 4: Subidas y bajadas de la residencia en RAM, Capítulo 5: Private Bytes y liberación |
| Se duda si reducir o deshabilitar el archivo de paginación | 6.3: El papel y el tamaño del archivo de paginación |
| El uso de RAM es alto pero no se ve ningún proceso grande | Capítulo 7: El desglose de la RAM física |
| Page Faults/sec es alto y se quiere saber si falta memoria | Capítulo 8: La diferencia entre fallos blandos y duros |
| Se quiere acotar la causa a partir de números registrados e investigar una fuga | Capítulo 10: Combinaciones de números, Capítulo 11: Procedimiento de investigación de fugas |
Si se quiere aprender el mecanismo desde el principio, léase en orden desde el capítulo 2; si ya hay registros, se puede empezar por la tabla del capítulo 10.
flowchart TB
accTitle: Elegir el indicador de memoria principal de Windows
accDescr: El indicador a mirar cambia según si se quiere saber la residencia en RAM, el Commit propio del proceso, el Commit de todo el sistema o el rango de direcciones virtuales
question["Qué se quiere saber con el «uso de memoria»"]
question -->|Cantidad ahora en RAM| workingSet["Working Set"]
question -->|Cantidad prometida de forma propia al proceso| privateBytes["Private Bytes"]
question -->|Cantidad prometida de todo el sistema| systemCommit["System Commit"]
question -->|Rango de direcciones reservado| virtualBytes["Virtual Bytes / Reserved"]
workingSet --> resident["Residencia en RAM física"]
privateBytes --> privateCommit["Commit propio del proceso"]
systemCommit --> commitLimit["Comparar con el Commit Limit"]
virtualBytes --> addressSpace["Espacio de direcciones virtuales"]
Figura 1: Descomponer primero la observación «hay mucha memoria» en cuatro tipos de pregunta.
En el diagrama, una línea continua marca una relación que siempre se cumple y una línea discontinua una relación condicional (las condiciones están en la explicación de cada relación en la página de detalle). La lista completa de relaciones (18 en total, con evidencia y grado de certeza) y las definiciones de los conceptos principales están reunidas en la página de detalle del mapa de conocimiento (en japonés). Datos: JSON-LD / Turtle
2. Dividir el «uso de memoria» en cuatro ejes
Los números distintos se pueden ordenar si se piensa que se está contando la misma página desde ángulos distintos. Aquí se separan en cuatro ejes: el estado de la dirección, el respaldo de los datos, la residencia en RAM y la posibilidad de compartirla con otros procesos.
flowchart TB
accTitle: Cuatro ejes independientes para clasificar una página
accDescr: Comprobar por separado el estado de la dirección virtual, el respaldo de una página con Commit, la residencia en RAM física y la posibilidad de compartirla con otros procesos
page["Una página vista en cuatro ejes"]
page --> address["Estado de la dirección"]
address --> addressValues["Free / Reserved / Committed"]
page --> backing["Respaldo"]
backing --> backingValues["Page-file-backed / File-backed"]
page --> residentAxis["Residencia en RAM"]
residentAxis --> residentValues["Resident / Not resident"]
page --> sharing["Posibilidad de compartir"]
sharing --> sharingValues["Private / Shareable"]
Figura 2: Incluso en una sola página, el estado de la dirección, el respaldo, la residencia y la posibilidad de compartir se deciden por separado.
No mezclar estado, respaldo y posibilidad de compartir
Mapped no es un estado de dirección al mismo nivel que Free, Reserved y Committed; es un tipo de región. Las páginas de una vista mapeada también pueden estar Committed.
Private, por su parte, no es un medio de respaldo, sino una clasificación de posibilidad de compartir. El respaldo se lee como page-file-backed o file-backed, y la posibilidad de compartir como Private o Shareable, por separado.
Comparar en qué indicadores se cuenta una página
Al combinar estos cuatro ejes, la relación entre los indicadores representativos queda así.
| Estado de la página | Working Set | Private Working Set | Private Bytes | Familia Virtual Bytes |
|---|---|---|---|---|
| Propia del proceso, con Commit, residente en RAM | Incluida | Incluida | Incluida | Incluida |
| Propia del proceso, con Commit, no residente en RAM | No incluida | No incluida | Incluida | Incluida |
| Página compartida de una DLL o archivo mapeado, residente en RAM | Incluida | En principio no incluida | En principio no incluida | Incluida |
| Reservada pero sin Commit | No incluida | No incluida | No incluida | Puede incluirse |
| Rango de direcciones no usado | No incluida | No incluida | No incluida | Normalmente no incluida |
flowchart TB
accTitle: Correspondencia entre tipos de página e indicadores principales de memoria
accDescr: Muestra en qué indicadores entran las páginas Private residentes, las Private no residentes, las compartidas residentes y los rangos solo reservados
privateResident["Private, con Commit, residente en RAM"]
privateNonresident["Private, con Commit, no residente en RAM"]
sharedResident["Página compartida, residente en RAM"]
reservedOnly["Reserved, sin Commit"]
workingSet["Working Set"]
privateWorkingSet["Private Working Set"]
privateBytes["Private Bytes"]
virtualBytes["Familia Virtual Bytes"]
privateResident --> workingSet
privateResident --> privateWorkingSet
privateResident --> privateBytes
privateResident --> virtualBytes
privateNonresident --> privateBytes
privateNonresident --> virtualBytes
sharedResident --> workingSet
sharedResident --> virtualBytes
reservedOnly --> virtualBytes
Figura 3: Working Set y Private Bytes cuentan conjuntos distintos de páginas, así que no hay una relación simple de inclusión.
No hay una relación fija de mayor o menor entre Working Set y Private Bytes
Lo importante aquí es que Working Set y Private Bytes no están en una relación simple de inclusión.
Private Bytes incluye páginas propias del proceso que ahora no están residentes en RAM. Working Set, en cambio, incluye páginas compartidas —código de DLL, memoria compartida, etc.— que Private Bytes no cuenta. Por eso, según el proceso y el momento, Working Set puede ser mayor que Private Bytes, y también puede ocurrir lo contrario.
Además, si se suman simplemente los Working Set de varios procesos, es posible contar más de una vez la misma página física, por ejemplo de una DLL compartida. «La suma de los Working Set de cada proceso = RAM en uso» no tiene por qué cumplirse.
3. Espacio de direcciones virtuales — Reserve y Commit son cosas distintas
«Reservar una dirección», «hacer Commit» y «tocar por primera vez una página para que entre en RAM» son hechos distintos. Este capítulo explica esas diferencias y, a partir de ellas, por qué una asignación puede fallar aunque haya RAM libre.
3.1. La dirección virtual no es la dirección de la RAM física
Cada proceso tiene su propio espacio de direcciones virtuales. Los punteros que maneja la aplicación no indican directamente una posición en la RAM física; Windows usa tablas de páginas para asociar direcciones virtuales con páginas físicas o con datos en un archivo.7
Por eso, incluso en un PC con 64 GB de RAM, el espacio de direcciones virtuales que puede usar un proceso de 32 bits concreto es normalmente mucho menor. A la inversa, un proceso de 64 bits con un espacio de direcciones virtuales mayor que la RAM física es perfectamente habitual.
3.2. Reserved solo «reserva la dirección»
MEM_RESERVE de VirtualAlloc reserva un rango contiguo de direcciones virtuales para usarlo en el futuro. En esta etapa no se asocia almacenamiento físico a las páginas, y ese rango no se puede leer ni escribir.45
Por ejemplo, aunque una base de datos o un runtime haya hecho Reserve de un rango de 8 GB para crecimiento futuro, eso por sí solo no significa que haya consumido 8 GB de RAM ni 8 GB de Private Bytes.
3.3. Committed es el estado en el que Windows promete «sostenerla cuando haga falta»
MEM_COMMIT pone esa página virtual en estado Committed y es la operación con la que Windows promete proporcionar el respaldo necesario. En el momento del Commit, la cantidad se carga contra el Commit Charge del sistema.5
Tener Commit no significa poder leer y escribir
Los permisos de lectura, escritura y ejecución se deciden aparte, con protecciones de página como PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE o PAGE_NOACCESS. Estar en Commit, por sí mismo, no significa «se puede leer y escribir».5
El Commit y la residencia en RAM también son etapas distintas
La página física real puede no asignarse hasta el primer acceso. La página que se toca por primera vez se inicializa a cero y, tras un Demand-zero fault, entra en el Working Set.51
Por tanto, aunque se hable de «haber reservado», hay las tres etapas siguientes.
flowchart TB
accTitle: Tres etapas desde Reserve hasta Commit y residencia en RAM
accDescr: Muestra el flujo de reservar un rango de direcciones virtuales, hacer Commit de la página y, en el primer acceso, asignar una página física que entra en el Working Set
reserve["MEM_RESERVE: reservar el rango de direcciones"]
reserve -.-> virtualMetric["Se refleja en la familia Virtual Bytes"]
reserve -->|MEM_COMMIT| committed["Con Commit: accesible según la protección de página"]
committed -.-> commitMetric["Se refleja en Private Bytes / System Commit"]
committed -->|Primer acceso, Demand-zero fault| resident["Asignar página física y residir en RAM"]
resident -.-> workingSetMetric["Se refleja en Working Set"]
committed -.->|Si no se ha accedido| nonresident["Con Commit pero no residente"]
Figura 4: Reserve, Commit y el primer acceso son hechos distintos y cada uno mueve un indicador distinto.
Estas tres etapas mueven por separado los números de la familia Virtual Bytes, de Private Bytes y de Working Set.
3.4. Por qué puede producirse un OutOfMemory aunque haya RAM libre
El éxito o el fallo de una asignación de memoria no se decide solo con la RAM libre.
- Se ha agotado el espacio de direcciones virtuales del proceso
- No hay un rango de direcciones libres contiguo del tamaño necesario
- El Commit Charge de todo el sistema ha llegado al Commit Limit
- Hay un límite propio de un Job Object, un contenedor, el runtime o una biblioteca
- El proceso es de 32 bits
- El montón nativo está fragmentado
Incluso en Windows de 64 bits, el espacio de direcciones virtuales en modo usuario de un proceso de 32 bits es normalmente de 2 GB si IMAGE_FILE_LARGE_ADDRESS_AWARE está desactivado. Una aplicación de 32 bits con ese bit activo puede usar hasta 4 GB en Windows de 64 bits.8
Por eso «el PC tiene 20 GB de RAM libre, pero la aplicación de 32 bits falla cerca de 1,6 GB» no es una contradicción. Puede no ser un problema de RAM, sino de fragmentación o de techo del espacio de direcciones.
4. Working Set — las páginas que están ahora en RAM
Working Set es el conjunto de páginas del espacio de direcciones virtuales del proceso que están actualmente residentes en RAM física.1
Ahí se mezclan, entre otras, las siguientes.
- El montón y la pila propios del proceso
- El código y los datos de solo lectura del EXE y de las DLL
- Archivos mapeados en memoria
- Memoria compartida
- Páginas que se volvieron propias del proceso tras un Copy-on-write
- Páginas tocadas por el runtime y por distintas bibliotecas
4.1. Que Working Set aumente no significa que haya aumentado la asignación
Si aumenta: puede que páginas ya existentes acaben de entrar en RAM
Si se accede por primera vez a una página que ya tenía Commit, Working Set puede subir sin que Private Bytes cambie.
También, si se mapea un archivo grande en memoria y se lee en orden, las páginas provenientes del archivo entran en el Working Set y Private Bytes apenas aumenta.
Si disminuye: puede que se siga reteniendo la misma memoria
Cuando Windows recorta (Trim) el Working Set ante presión de memoria, la aplicación sigue reteniendo lógicamente la misma memoria y solo baja el Working Set. Si más adelante se vuelve a tocar, regresa tras un Page Fault.
Es decir, una subida de Working Set no significa necesariamente «se acaba de reservar» y una bajada no significa necesariamente «se ha liberado». Hay que leer por separado el cambio de residencia y la asignación o liberación.
flowchart TB
accTitle: Flujos típicos en los que solo sube o baja Working Set
accDescr: Mientras la misma página con Commit entra en RAM en el primer acceso, deja de ser residente por Trim y vuelve en un nuevo acceso, Private Bytes sigue contándose
committed["La misma página con Commit"]
committed -->|Primer acceso| resident["Residente en RAM"]
resident -->|Trim por presión de memoria| nonresident["No residente"]
nonresident -->|Page Fault al volver a acceder| resident
resident -.-> inWorkingSet["Incluida en Working Set"]
nonresident -.-> outsideWorkingSet["No incluida en Working Set"]
committed -.-> privateBytes["Mientras hay Commit, se cuenta en Private Bytes"]
Figura 5: Working Set sube y baja según el estado de residencia, pero Private Bytes no baja mientras siga el Commit de esa misma página.
4.2. Working Set incluye páginas compartidas
Si diez procesos comparten la misma página de código de una DLL, esa página puede aparecer en el Working Set de cada proceso, aunque en la RAM física solo exista un ejemplar. Que la suma de los Working Set supere la RAM instalada no es, por sí sola, una anomalía.
Si se quiere aproximarse a «la RAM que este proceso ocupa ahora en exclusiva», se mira Private Working Set. Aun así, tampoco es «toda la memoria que la aplicación ha reservado»: son únicamente las páginas Private actualmente residentes.
4.3. Reducir Working Set a la fuerza no corrige una fuga de memoria
Con EmptyWorkingSet o SetProcessWorkingSetSize se pueden expulsar páginas del Working Set del proceso. Sin embargo, esa operación no libera el Commit ni las referencias en el montón. Private Bytes puede no cambiar y bajar solo el uso aparente de RAM; en el siguiente acceso pueden aumentar los Page Fault.9
Si el número del Administrador de tareas se reduce solo justo después de pulsar un botón de «liberar memoria» y, al reanudar el trabajo, vuelve enseguida al valor anterior, es posible que no se haya «liberado» nada, sino solo recortado el Working Set.
5. Private Bytes — la cantidad de Commit propia del proceso
Private Bytes es la cantidad de memoria virtual con Commit reservada de forma exclusiva para ese proceso. Representa el Commit Charge que no se puede compartir con otro proceso, con independencia de si ahora está residente en RAM. En PROCESS_MEMORY_COUNTERS_EX de Microsoft, PrivateUsage corresponde a este valor.102
La API Win32 también tiene el campo de nombre engañoso PagefileUsage, pero la documentación actual lo define como «el Commit Charge de ese proceso» y explica que es el mismo valor que PrivateUsage. Es decir, 2 GB de Private Bytes no significa que se hayan escrito 2 GB en pagefile.sys.2
En Private Bytes influyen, de forma representativa, los siguientes.
- El Commit del montón nativo que usan
HeapAlloc,malloc,new, etc. - Private Data con Commit directo mediante
VirtualAlloc - La región con Commit del montón del GC de .NET
- La parte realmente con Commit de las pilas de los hilos
- El Commit Charge de toda la vista que se reserva al mapear una vista Copy-on-write (
FILE_MAP_COPY) - Búferes Private que retienen internamente bibliotecas o SDK de dispositivos
En Copy-on-write, además, la contabilización puede adelantarse a la escritura real. Como cada página de una vista creada con FILE_MAP_COPY puede volverse Private en el futuro, en el momento del mapeo se reserva el Commit Charge necesario para respaldar toda la vista con el archivo de paginación.11
Por eso, incluso antes de escribir y de que se cree la copia Private, el System Commit y el Commit Charge del proceso (Private Bytes) pueden aumentar en el tamaño de toda la vista.11
5.1. Por qué Private Bytes no baja después de free o del GC
Separar la liberación dentro de la aplicación de la operación de devolver memoria al SO
Aunque desde la aplicación se «libere» memoria, el runtime o el asignador del montón puede no hacer Decommit de esa región hacia el SO y retenerla para reutilizarla más adelante. En ese caso, internamente es reutilizable, pero Private Bytes se mantiene alto.
También se queda alto si solo sobrevive una parte de una región grande, si hay fragmentación, o si una caché o un pool se ha calentado hasta su techo.
Comparar el cambio tras la misma carga, no el valor que se ha quedado alto
Que Private Bytes sea alto no demuestra, por sí solo, una fuga. Se compara la diferencia en el tiempo, en este orden.
- Se repite el mismo procesamiento, el mismo número de veces.
- Después de cada procesamiento, se espera el mismo tiempo.
- Se comprueba si Private Bytes vuelve al mismo nivel o si se estabiliza en un valor concreto.
- Con VMMap o un volcado del montón se comprueba qué región o tipo ha aumentado.
flowchart TB
accTitle: Por qué Private Bytes no baja después de free o del GC
accDescr: El cambio de Private Bytes difiere según si el asignador devuelve al SO la región que la aplicación ya no necesita o la retiene para reutilizarla
release["La aplicación la marca como innecesaria con free / GC"]
release --> decision{"¿El asignador la devuelve al SO?"}
decision -->|Decommit / Release| returned["Baja el Commit Charge"]
returned --> lower["Baja Private Bytes"]
decision -->|La retiene para reutilizarla| retained["La región sigue con Commit"]
retained --> high["Private Bytes se queda alto"]
retained --> reasons["Pool, caché, fragmentación"]
Figura 6: Que algo sea reutilizable dentro de la aplicación y que se haya devuelto el Commit al SO no son lo mismo.
5.2. La forma más sospechosa de una fuga
Un aumento «en escalera», en el que el suelo sube con cada carga, es especialmente sospechoso.
Private Bytes
^
| ________
| ______|
| ______|
|_____|
+----------------------------> repetición del mismo procesamiento
Aun así, un patrón en escalera puede crecer solo unas cuantas veces por el JIT inicial, fuentes, decodificadores de imagen, pools de conexión o el calentamiento de una caché, y estabilizarse después. Más importante que el hecho de que aumente es que no converja a un estado estable.
6. System Commit — qué es realmente «Comprometido X/Y»
Hasta aquí se han visto sobre todo indicadores de un solo proceso. «Comprometido X/Y», en [Rendimiento] → [Memoria] del Administrador de tareas, es un indicador de todo el sistema. Hay que leerlo aparte de los valores de cada proceso.
- X: System Commit Charge
La memoria con Commit que Windows promete sostener ahora en todo el sistema - Y: System Commit Limit
El techo de Commit que el sistema puede sostener
El Commit Limit se determina, a grandes rasgos, por la suma de la RAM física y de todos los archivos de paginación. Si no hay archivo de paginación, queda un poco por debajo de la RAM instalada.36
flowchart TB
accTitle: Relación entre System Commit Charge y Commit Limit
accDescr: El Commit propio de los procesos, el de las secciones compartidas y el del kernel forman el valor actual X, y la RAM física y el archivo de paginación sostienen el techo Y
processCommit["Private Commit de cada proceso"] --> charge["System Commit Charge: X"]
sharedCommit["Commit de secciones compartidas respaldadas por el archivo de paginación"] --> charge
kernelCommit["Commit del kernel"] --> charge
physicalRam["RAM física"] --> limit["System Commit Limit: Y"]
pageFiles["Archivo de paginación"] --> limit
charge -->|X no puede superar Y| limit
Figura 7: X es la cantidad prometida ahora e Y es el techo que puede sostener esa promesa; no es una visualización del uso del archivo de paginación.
El System Commit Charge incluye no solo la suma de Private Bytes de cada proceso, sino también el Commit de secciones compartidas respaldadas por el archivo de paginación y el Commit que consume el kernel. Por eso, la suma de Private Bytes por proceso no explica X por completo.
6.1. Commit Charge no es el uso del archivo de paginación
Los 20 GB de «20/31 GB» no son una cantidad en disco
Piense en un sistema con 16 GB de RAM, 16 GB de archivo de paginación y Committed 20/31 GB.
Esos 20 GB no significan «se han escrito 20 GB en el archivo de paginación». Son el total que Windows promete respaldar, cuando haga falta, con RAM, archivo de paginación u otro respaldo, para páginas privadas modificables y similares.
Dentro de esos 20 GB se mezclan estados como los siguientes.
- Gran parte está residente en RAM
- Una parte se ha retirado al archivo de paginación
- Tiene Commit pero todavía no se ha accedido por primera vez
- Se consume como Commit del lado del kernel
La tasa de uso del archivo de paginación se mira en otro contador
Si se quiere ver el uso real del archivo de paginación, se comprueba Paging File(*)\% Usage aparte del Commit. Aun así, la documentación de Microsoft explica que un uso alto del archivo de paginación no implica por sí solo un problema de rendimiento, y que hay que juzgarlo junto con la llegada al Commit Limit, la Modified Page List y la E/S real de paginación.6
6.2. Qué ocurre al acercarse al Commit Limit
Cuando el System Commit Charge llega al Commit Limit, no se pueden sostener nuevas peticiones de Commit. Eso puede llevar a fallos de asignación de memoria en procesos, a caídas de aplicaciones o a que el sistema deje de responder.3
Aquí importa más el X/Y de Commit que la «RAM libre». Recortar el Working Set para crear RAM libre no resuelve la llegada al Commit Limit si el propio Commit Charge no disminuye.
6.3. Las tres funciones del archivo de paginación
El archivo de paginación tiene, principalmente, las funciones siguientes.
- Ampliar el Commit Limit
- Permitir retirar de la RAM páginas modificadas de uso poco frecuente
- Sostener, según la configuración, el volcado de memoria del sistema en caso de fallo
La deshabilitación o el cambio de tamaño se deciden con el Commit de pico y los requisitos de volcado
No hay una relación simple del tipo «si se deshabilita el archivo de paginación, baja necesariamente la E/S de disco y el sistema va más rápido». Más bien se baja el Commit Limit, se hace más fácil dejar en RAM páginas modificadas que no se van a usar de momento, y puede volverse imposible recoger el volcado necesario en un fallo.36
El tamaño adecuado del archivo de paginación no se decide solo con la RAM instalada. Microsoft también explica que no se puede generalizar, porque el System Commit Charge de pico y el tipo de volcado de memoria necesario varían de un sistema a otro.6
7. El desglose de la RAM física — no juzgar solo porque Available sea bajo
La RAM física no se usa solo para el Working Set de los procesos de usuario.
- Working Set de cada proceso
- Caché de archivos del sistema
- Listas de páginas Standby, Modified, Free, Zeroed, etc.
- Paged Pool / Nonpaged Pool del kernel
- Memoria retenida por controladores de dispositivo
- Almacén de compresión de memoria
- Regiones compartidas o reservadas con la GPU u otros dispositivos
- Reserva de hardware
7.1. Available incluye caché reutilizable
Free y Available no significan lo mismo. El Available MBytes de Windows incluye, además de Free y Zeroed, las páginas Standby que se pueden reutilizar si hace falta. No es un indicador que cuente solo la RAM completamente sin uso.12
- Free: páginas que ahora no están asignadas a ningún uso
- Zeroed: páginas ya puestas a cero para poder entregarlas de forma segura a otro proceso
- Standby: páginas que salieron del Working Set pero cuyo contenido sigue en caché en RAM
- Modified: páginas cuyo contenido ha cambiado y que, antes de reutilizarse, hay que escribir de vuelta en el respaldo adecuado
flowchart TB
accTitle: Movimiento entre Working Set y las listas de páginas
accDescr: Muestra el flujo en el que una página en uso pasa a Standby si no está modificada o a Modified si lo está, y después se reacciona, se escribe de vuelta o se reutiliza
workingSet["Working Set: en uso"]
workingSet -->|Quitar una página no modificada| standby["Standby: candidata a reutilización que conserva el contenido"]
workingSet -->|Quitar una página modificada| modified["Modified: a la espera de escritura de vuelta"]
modified -->|Escritura de vuelta completada| standby
standby -->|Nuevo acceso| workingSet
standby -->|Reutilizar para otro uso| reused["Asignar a otro uso"]
free["Free: sin uso"] -->|Puesta a cero| zeroed["Zeroed: asignable de nuevo"]
zeroed -->|Acceso tras la asignación| workingSet
standby -.-> available["Incluida en Available"]
free -.-> available
zeroed -.-> available
Figura 8: Available incluye no solo el espacio completamente libre, sino también Standby, que se puede reutilizar si hace falta.
Separar que Free sea bajo de la presión de memoria física
«Tirar toda la caché para aumentar la RAM libre» no siempre sale a cuenta. Si en Standby queda un dato que se va a necesitar, un nuevo acceso puede devolverlo al Working Set con rapidez, sin leer el disco.
Por tanto, aunque Free sea bajo en el Administrador de tareas, si Available es suficiente y no hay problema de hard page fault ni de espera de disco, puede que Windows esté usando la RAM de forma eficaz como caché.
7.2. Cuando la RAM disminuye sin que haya procesos grandes
No es raro un consumo de memoria que no se explica sumando el Private Working Set de cada proceso.
- Caché de archivos o archivos mapeados en memoria
- Nonpaged Pool / Paged Pool
- Páginas bloqueadas por un controlador
- Páginas compartidas
- Compresión de memoria
- Asignaciones relacionadas con virtualización o GPU
En ese caso, más que seguir mirando la lista de procesos, conviene comprobar Use Counts, Processes, Priority Summary y File Summary con RAMMap de Sysinternals. RAMMap es la herramienta oficial para descomponer la memoria física por uso, por lista de páginas y por archivo.13
Si lo que no deja de crecer es solo Nonpaged Pool, ya no se trata de Private Bytes de una aplicación en modo usuario, sino de sospechar una fuga en un controlador o en el lado del kernel.
8. Page Fault — que sean muchos no significa que haya un problema
Un Page Fault se produce cuando un proceso accede a una página que ahora no está en su Working Set. Aunque el nombre lleve «Fault», no es un fallo excepcional: es el mecanismo habitual que hace funcionar la memoria virtual.1
Lo primero que hay que separar es si hace falta leer el disco. Después se miran, junto con el número de sucesos, el tiempo de espera real y el empeoramiento de la respuesta.
8.1. Soft page fault
Se resuelve sin leer el disco.
- La página sigue en Standby o Transition
- Otro proceso tiene la misma página compartida en su Working Set
- Se accede por primera vez a una página con Commit y se asigna una página a cero
- La página ya está en RAM por lectura anticipada del administrador de memoria
Por eso, que \Memory\Page Faults/sec sea alto no implica necesariamente E/S de disco ni latencia.
8.2. Hard page fault
Hace falta leer el contenido desde un Backing Store en disco. El origen de la lectura no se limita al archivo de paginación.
- Código y datos de
.exeo.dll - Archivos mapeados en memoria
- Archivo de paginación
flowchart TB
accTitle: Bifurcación entre soft page fault y hard page fault
accDescr: Al acceder a una página que no está en el Working Set, si no hace falta E/S de almacenamiento se trata como soft page fault, y si hace falta, como hard page fault
access["Acceso a una página que no está en el Working Set"] --> storageIo{"¿Hace falta E/S de almacenamiento?"}
storageIo -->|No: Standby, compartida, Demand-zero, etc.| soft["Soft page fault"]
soft --> resident["Entra en el Working Set sin leer disco"]
storageIo -->|Sí| hard["Hard page fault"]
hard --> source{"¿Desde dónde se lee?"}
source --> image["EXE / DLL"]
source --> mapped["Archivo mapeado en memoria"]
source --> pagefile["Archivo de paginación"]
image --> loaded["Tras la lectura, entra en el Working Set"]
mapped --> loaded
pagefile --> loaded
Figura 9: El nombre Page Fault, por sí solo, no permite decidir si hay E/S de disco.
Microsoft cita como contadores para medir hard fault \Memory\Pages/sec, \Memory\Page Reads/sec, \Memory\Pages Input/sec, entre otros. Aunque estén altos, no equivalen necesariamente a poca memoria, así que hay que correlacionarlos con Available MBytes, la latencia de disco y el tiempo de respuesta real.6
8.3. No fijar un umbral uniforme
Un valor fijo del tipo «si Page Faults/sec supera 1000, hay una anomalía» cambia de significado según el almacenamiento, el tamaño de página, la carga de trabajo y la localidad de acceso.
En la práctica se colocan en el mismo eje temporal, como mínimo, los siguientes.
Memory\Available MBytesMemory\Pages Input/secMemory\Page Reads/sec- Read latency / Queue del disco afectado
- Working Set y Private Bytes del proceso objetivo
- Tiempo de procesamiento de la aplicación, tiempos de espera, respuesta de la IU
Si, al mismo tiempo que sube la carga, baja Available, suben Pages Input/sec y la espera de disco, y también empeora el tiempo de procesamiento, se reúnen indicios para sospechar paginación por presión de memoria física.
9. Qué pantalla o herramienta usar para ver cada cosa
Si se decide primero si el objetivo es un proceso o todo el sistema, y si se quiere un desglose de un instante o una serie temporal, resulta más fácil elegir la herramienta. En la tabla siguiente se hace corresponder indicadores y herramientas, y después se pasa al registro.
| Lo que se quiere saber | Indicador a mirar primero | Herramientas principales |
|---|---|---|
| Cuánto tiene ahora el proceso objetivo en RAM | Working Set | Administrador de tareas, Process Explorer, Get-Process |
| De eso, la RAM propia del proceso | Private Working Set / Working Set - Private | Columnas detalladas del Administrador de tareas, Process Explorer, PerfMon |
| Cantidad de Commit propia del proceso objetivo | Private Bytes / Commit Size | Process Explorer, PerfMon, VMMap, Get-Process |
| Rango de direcciones virtuales del proceso | Virtual Bytes / Size | Process Explorer, VMMap, Get-Process |
| Margen de Commit de todo el sistema | Committed Bytes / Commit Limit | Administrador de tareas [Rendimiento], PerfMon |
| Margen de reutilización de la RAM física | Available MBytes | Administrador de tareas, PerfMon |
| Desglose de Standby, Modified y caché de archivos | Listas de páginas y desglose por uso | RAMMap |
| Qué ha aumentado dentro de Private Bytes | Heap / Private Data / Managed Heap, etc. | VMMap, WinDbg, volcados según el runtime |
| Paginación con disco | Pages Input/sec, Page Reads/sec, latencia de disco | PerfMon, WPR/WPA |
flowchart TB
accTitle: Elegir la herramienta de investigación de memoria de Windows
accDescr: La herramienta a usar cambia según si el objetivo es un proceso o todo el sistema, si se quiere un instante o una serie temporal, y si hay que seguir hasta el interior del runtime
question["Qué se quiere aislar"]
question --> processScope{"¿El objetivo es un proceso?"}
processScope -->|Sí| processTime{"¿Un instante o una serie temporal?"}
processTime -->|Desglose de un instante| vmmap["VMMap"]
processTime -->|Serie temporal| perfmon["PerfMon / PowerShell"]
processScope -->|Todo el sistema| systemView{"¿Desglose de RAM física o eje temporal?"}
systemView -->|Desglose de RAM física| rammap["RAMMap"]
systemView -->|Eje temporal que incluye CPU, E/S y espera| wpa["WPR / WPA"]
question --> runtime{"¿Hay que seguir hasta lo que retiene el runtime?"}
runtime -->|Montón de .NET| dotnet["dotnet-dump / PerfView"]
runtime -->|Montón nativo| native["WinDbg / Application Verifier"]
Figura 10: Si se decide primero el alcance y el eje temporal, se pueden elegir las herramientas necesarias sin quedarse cortos ni pasarse.
9.1. Administrador de tareas
En el Administrador de tareas se mira cada pantalla por separado.
- [Procesos] o [Detalles]: familia Working Set y familia Commit Size de cada proceso
- [Rendimiento] → [Memoria]: In use, Available, Committed, Cached, Paged pool y Non-paged pool de todo el sistema
No se juzga solo por el nombre de columna «Memoria»: en la pestaña [Detalles] se hace clic con el botón derecho en el encabezado de columnas y se añaden las que hagan falta, como Working Set, Peak Working Set o Commit Size. El nombre de las columnas varía un poco según la versión de Windows y el idioma de visualización, así que se registra después de confirmar el significado de cada columna.
9.2. Obtener una serie temporal con PowerShell
Primero, registrar tres indicadores del mismo proceso
Si se conoce el ID del proceso objetivo, Get-Process permite tomar a la vez la pendiente de Working Set, Private Bytes y Virtual Bytes.
param(
[Parameter(Mandatory)]
[int]$ProcessId,
[int]$IntervalSeconds = 5,
[int]$SampleCount = 60
)
$samples = for ($i = 0; $i -lt $SampleCount; $i++) {
$process = Get-Process -Id $ProcessId -ErrorAction Stop
[pscustomobject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
ProcessId = $process.Id
WorkingSetMB = [math]::Round($process.WorkingSet64 / 1MB, 1)
PrivateBytesMB = [math]::Round($process.PrivateMemorySize64 / 1MB, 1)
VirtualBytesMB = [math]::Round($process.VirtualMemorySize64 / 1MB, 1)
Handles = $process.HandleCount
Threads = $process.Threads.Count
}
Start-Sleep -Seconds $IntervalSeconds
}
$samples | Format-Table -AutoSize
$samples | Export-Csv .\memory-samples.csv -NoTypeInformation -Encoding utf8
Process.WorkingSet64 de .NET corresponde a Working Set, PrivateMemorySize64 a Private Bytes y VirtualMemorySize64 a Virtual Bytes.141516
Evitar confusiones por varias instancias o por un reinicio
En una aplicación con varias instancias, se sigue por PID, no por nombre. En una supervisión larga en la que el PID cambia al reiniciar, hace falta un diseño que registre también la hora de arranque o el nombre del servicio, para no confundir el objetivo.
9.3. Alinear sistema y proceso en el mismo eje temporal con PerfMon
Como mínimo, registrar a la vez lo siguiente facilita el aislamiento.
\Process(<objetivo>)\ID Process
\Process(<objetivo>)\Working Set
\Process(<objetivo>)\Working Set - Private
\Process(<objetivo>)\Private Bytes
\Process(<objetivo>)\Virtual Bytes
\Memory\Available MBytes
\Memory\Committed Bytes
\Memory\Commit Limit
\Memory\Pages Input/sec
\Memory\Page Reads/sec
\Memory\Pool Nonpaged Bytes
\Memory\Pool Paged Bytes
Comprobar no solo el nombre de instancia, sino también el PID de cada muestra
Si hay varios procesos del mismo nombre, o si se reinicia durante la supervisión, el nombre de instancia Process(name) o Process(name#N) no basta para fijar el objetivo. En cada muestra se registra también ID Process y solo se adoptan las instancias cuyo valor coincide con el PID que se está siguiendo. Si el PID cambia al cruzar un reinicio, se registra además el momento del cambio.
Si no aparece un contador, comprobar el idioma de visualización
Los nombres de los contadores de rendimiento de Windows pueden estar localizados según el idioma de visualización. Si al especificar el nombre en inglés desde PowerShell no se encuentra, se añade desde la interfaz de PerfMon o se confirma el nombre del entorno local con Get-Counter -ListSet *.
9.4. No confundir los papeles de VMMap y RAMMap
- VMMap: descompone la memoria virtual y el Working Set de un proceso en Heap, Image, Mapped File, Private Data, Managed Heap, etc.
- RAMMap: descompone la RAM física de todo el sistema por uso, lista de páginas, proceso y archivo
«De qué ha aumentado el Private Bytes de este proceso» es VMMap; «en qué se ha usado la RAM que no explica la lista de procesos» es RAMMap.1713
10. Leer los síntomas a partir de la combinación de números
Los valores registrados se leen según qué indicadores se mueven juntos y cuáles no cambian. La tabla siguiente no sirve para afirmar la causa, sino para elegir el desglose o las condiciones que conviene comprobar a continuación.
| Forma observada | Lo primero que hay que pensar | Qué comprobar a continuación |
|---|---|---|
| Sube Working Set y Private Bytes se mantiene | Primer acceso a páginas existentes, DLL compartidas, archivos mapeados, caché de archivos | Image / Mapped File de VMMap, Pages Input/sec |
| Sube Private Bytes y Working Set se mantiene | Ha aumentado el Commit Private, pero no está residente o se ha recortado | Heap / Private Data / Managed Heap de VMMap |
| Ambos suben justo después del arranque y luego se aplanan | JIT, caché, pool, calentamiento de la inicialización | Si vuelve a subir al añadir la misma carga |
| El suelo de Private Bytes sube con cada carga | Fuga, caché sin techo, asignador que retiene tras liberar | Instantáneas de VMMap de antes y después, volcado del montón |
| Solo Working Set baja de golpe y vuelve con la operación | El SO o la aplicación ha recortado el Working Set | Private Bytes, Pages Input/sec, tiempo de respuesta |
| La X de Comprometido X/Y se acerca a Y | Presión de Commit de todo el sistema | Procesos con más Private Bytes, Paged/Nonpaged Pool, configuración del archivo de paginación |
| Available es bajo y Pages Input/sec y la latencia de disco son altos | Presión de RAM física y paginación dura | Procesos con más Working Set, RAMMap, correlación con la carga |
| El uso de RAM es alto pero no hay procesos grandes | Caché, páginas compartidas, pool del kernel, controladores, compresión, etc. | RAMMap, Pool Nonpaged/Paged Bytes |
| Hay RAM libre pero solo falla la aplicación de 32 bits | Techo o fragmentación del espacio de direcciones virtuales | Free/Reserved de VMMap, configuración LAA del ejecutable |
| Private Bytes es alto pero no sube al repetir el procesamiento | Posible pool o caché que retiene una marca de agua alta | Techo, reutilización, estabilidad después del pico |
Lo más importante de esta tabla es leer por combinación, no por un valor aislado.
11. Procedimiento práctico para investigar una fuga de memoria
La investigación avanza en cinco etapas: fijar las condiciones de comparación → registrar a la vez → identificar el indicador que aumenta → examinar el desglose → comparar antes y después de la corrección. No se pasa al volcado en cuanto se ve un valor grande: primero se acota qué está aumentando.
11.1. Primero, definir las condiciones de reproducción y el punto estable
«Aumenta en unos días» no basta para comparar. Para poder comparar la versión correcta y la problemática en las mismas condiciones, se decide primero lo siguiente.
- Hasta dónde incluir el calentamiento posterior al arranque
- El contenido de las operaciones de un ciclo
- Cuántos segundos esperar después de un ciclo
- Cuántas veces hacen falta hasta llegar al techo de la caché
- Si se puede usar la misma entrada en la versión correcta y en la problemática
11.2. Registrar el proceso y el sistema al mismo tiempo
Como mínimo se dejan, a la misma hora, los siguientes.
- Working Set del objetivo
- Private Bytes del objetivo
- Virtual Bytes del objetivo
- Committed Bytes / Commit Limit del sistema
- Available MBytes
- Pages Input/sec
- Número de handles y de hilos
- Número de operaciones o de elementos procesados
Si Private Bytes del proceso se mantiene estable y solo aumenta el Commit del sistema, hay que ampliar el campo de visión a otros procesos, al kernel, a controladores, a secciones compartidas, etc.
11.3. Decidir primero qué «dimensión» está aumentando
- Solo Working Set: páginas residentes, origen compartido o de archivo, recorte y recarga
- Private Bytes: Commit propio del proceso
- Solo Virtual Bytes: Reserve, mapeo, fragmentación del espacio de direcciones
- Solo System Commit: incluye otros procesos y el lado del kernel
- Nonpaged Pool: lado de controladores y kernel
- Handles / GDI / USER: fuga de un recurso distinto de la memoria
Si se salta este orden y se toma un volcado de entrada, se acaba leyendo una gran cantidad de información sobre un objetivo equivocado.
11.4. Pasar al desglose
- Proceso nativo: VMMap, WinDbg, Application Verifier, seguimiento del montón
- .NET:
dotnet-counters,dotnet-gcdump,dotnet-dump, PerfView - Todo el sistema: RAMMap, PerfMon, WPR/WPA
- Pool del kernel: PoolMon, WinDbg
VMMap muestra, por tipo, la memoria virtual con Commit del proceso y el Working Set asignado a cada una. El coste de la investigación posterior cambia mucho según si el aumento de Private Bytes se puede acotar a «Heap», «Private Data», «Managed Heap» o «Mapped File».17
11.5. Después de corregir, comparar la pendiente en las mismas condiciones
Que el valor de pico sea distinto antes y después de la corrección no basta. Si el valor inicial es distinto, el resultado se invierte con facilidad. Se igualan las condiciones siguientes y se comparan el suelo y la pendiente después de cada ciclo.
- El mismo estado de arranque
- La misma entrada
- El mismo número de operaciones
- El mismo tiempo de espera
- El mismo intervalo de muestreo
La prueba de que se ha corregido una fuga no es «el máximo se ha hecho más pequeño», sino que el aumento converge aunque se repita la misma carga.
12. Reformular los malentendidos habituales
Malentendido 1: La memoria del Administrador de tareas = todo lo que reservó la aplicación
Reformulación: Confirmar de qué columna se trata. Si es de la familia Working Set, es la cantidad ahora residente en RAM; si es de la familia Commit Size, es la cantidad de Commit propia del proceso.
Malentendido 2: Private Bytes = bytes que hay en el archivo de paginación
Reformulación: Private Bytes es el Commit Charge Private. Es una cantidad lógica prometida que incluye tanto páginas que están en RAM como páginas que, si hace falta, se sostienen con el archivo de paginación.
Malentendido 3: Commit X/Y = uso del archivo de paginación / capacidad del archivo de paginación
Reformulación: X es el Commit Charge de todo el sistema e Y es el Commit Limit. El archivo de paginación amplía Y, pero X no se convierte tal cual en uso en disco.
Malentendido 4: Page Faults/sec alto = se está intercambiando con el disco
Reformulación: También incluye fallos blandos. Si hay E/S de disco se confirma con Pages Input/sec o Page Reads/sec y con la latencia de disco.
Malentendido 5: Poca RAM Free = falta de memoria
Reformulación: Mirar Available, Standby, paginación dura y tiempo de respuesta. Llenar la RAM con caché reutilizable es normal.
Malentendido 6: Haber reducido Working Set = haber corregido una fuga de memoria
Reformulación: Puede que solo se hayan expulsado páginas de la RAM. Hay que comprobar si han bajado Private Bytes y lo que se retiene en el montón.
Malentendido 7: Que Private Bytes haya aumentado confirma una fuga
Reformulación: Solo se puede juzgar después de comprobar si converge al repetir la misma carga de trabajo, qué tipo de memoria ha aumentado y si es caché liberable.
13. Resumen
Primero, decidir qué está contando cada número
El «uso de memoria» de Windows no es un solo número. Hay que pensar por separado el espacio de direcciones, el Commit, la residencia en RAM y la posibilidad de compartir.
Working Set son las páginas que están ahora en RAM, e incluye tanto Private como Shared. Private Working Set son, de esas, las páginas residentes propias del proceso. Private Bytes, en cambio, es el Commit Charge propio del proceso: no es la cantidad ahora en RAM ni la cantidad realmente escrita en el archivo de paginación.
Después, leer por separado reserva, residencia y paginación
El rango de direcciones virtuales en Reserve, la página con Commit y la página que se ha tocado de verdad y ha entrado en el Working Set son etapas distintas.
Committed X/Y indica el Commit Charge / Commit Limit de todo el sistema. El archivo de paginación sostiene, sobre todo, la ampliación del Commit Limit, la retirada de páginas modificadas y el volcado de memoria en caso de fallo.
Un Page Fault es un funcionamiento habitual, y un fallo blando no lee el disco. El origen de lectura de un fallo duro tampoco se limita al archivo de paginación: incluye EXE, DLL y archivos mapeados.
En la investigación, comparar suelo, pendiente y desglose después de la misma carga
Una fuga de memoria se demuestra no por el tamaño en un instante, sino por el suelo y la pendiente después de la misma carga, y por el desglose.
Lo básico es pasar al desglose de un proceso con VMMap, a la RAM física de todo el sistema con RAMMap, a la serie temporal con PerfMon, y al interior del runtime con herramientas de volcado específicas.
La próxima vez que en el Administrador de tareas se note que «la memoria está aumentando», conviene preguntarse primero esto.
¿Lo que está aumentando es Working Set, Private Bytes, Virtual Bytes o System Commit?
Solo con esta pregunta, el punto de partida de la investigación se vuelve mucho más preciso.
Artículos relacionados
- Cómo distinguir la espera de GC de una fuga de memoria en .NET — Procedimiento práctico para observar, comparar y demostrar el crecimiento de memoria
- Process Explorer / Handle / VMMap en la práctica — Cómo rastrear cuelgues, fugas y «archivo en uso» desde el estado actual
- Trampas de la memoria compartida y buenas prácticas para producción
- Las profundidades de la E/S de Windows (parte 4) — El administrador de caché: ¿cuándo llega su WriteFile al disco?
- Investigación de un crash en una cámara industrial tras un largo funcionamiento - Edición fuga de handles
Áreas de consultoría relacionadas
En KomuraSoft LLC nos encargamos de investigar la causa raíz del crecimiento de memoria en aplicaciones de Windows, la degradación de rendimiento tras un uso prolongado, el OutOfMemory en procesos de 32 bits y la falta de memoria que solo se produce en el entorno del cliente, combinando PerfMon, VMMap, RAMMap, WinDbg y herramientas de diagnóstico de .NET. No nos quedamos en un simple «hay mucha memoria»: aislamos qué región, con qué operación, por qué aumenta y desde dónde se referencia o retiene.
- Desarrollo de aplicaciones Windows
- Investigación de fallos y análisis de causa raíz
- Consultoría técnica y revisión de diseño
- Contacto
Referencias
-
Microsoft Learn, Working Set. Sobre que el Working Set de un proceso es el conjunto de páginas actualmente residentes en memoria física, que incluye páginas compartidas, la diferencia entre fallos de página blandos y duros, las páginas Transition y la eliminación de páginas del Working Set. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, PROCESS_MEMORY_COUNTERS_EX2 structure. Sobre la definición de WorkingSetSize, PrivateWorkingSetSize, PrivateUsage y SharedCommitUsage, y sobre que tanto PagefileUsage como PrivateUsage representan el Commit Charge del proceso. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Introduction to page files. Sobre que el archivo de paginación sostiene la retirada de páginas modificadas, el volcado del sistema y la ampliación del System Commit Limit, sobre la definición de System Commit Charge y Commit Limit, y sobre su medición en el Administrador de tareas y en los contadores de rendimiento. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Page State. Sobre los estados Free, Reserved y Committed de una página virtual, y sobre que a una página Reserved no se le asocia almacenamiento físico y no se puede acceder a ella. ↩ ↩2
-
Microsoft Learn, VirtualAlloc function. Sobre la diferencia entre MEM_RESERVE y MEM_COMMIT, sobre que al hacer Commit se carga contra la memoria y el archivo de paginación de todo el sistema, y sobre que la página física real puede no asignarse hasta el primer acceso. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, How to determine the appropriate page file size for 64-bit versions of Windows. Sobre que el tamaño del archivo de paginación depende del Commit Charge en el pico y de los requisitos de volcado, sobre que el origen de lectura de un fallo de página duro no se limita al archivo de paginación e incluye EXE, DLL y archivos mapeados en memoria, y sobre los contadores de rendimiento relacionados. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Virtual Address Space. Sobre que cada proceso tiene un espacio de direcciones virtuales y una tabla de páginas independientes, y sobre que una dirección virtual no es en sí misma una dirección física. ↩
-
Microsoft Learn, Memory Limits for Windows and Windows Server Releases. Sobre que el espacio de direcciones virtuales en modo usuario de un proceso de 32 bits es normalmente de 2 GB, y sobre que en Windows de 64 bits pasa a ser de 2 GB o 4 GB según haya o no IMAGE_FILE_LARGE_ADDRESS_AWARE. ↩
-
Microsoft Learn, SetProcessWorkingSetSize function. Sobre que los valores mínimo y máximo del Working Set no garantizan la residencia, que se puede vaciar el Working Set, y sobre que una configuración u operación excesiva puede degradar el rendimiento del sistema. ↩
-
Microsoft Learn, Memory Performance Information. Sobre la correspondencia entre los contadores de rendimiento de Windows, las API de gestión de memoria y lo que muestra el Administrador de tareas, incluyendo Working Set, Working Set - Private y Private Bytes del proceso, y Committed Bytes y Commit Limit del sistema. ↩
-
Microsoft Learn, MapViewOfFile function. Sobre que, con
FILE_MAP_COPY, todas las páginas pueden llegar a ser Copy-on-write, por lo que en el momento del mapeo se reserva el Commit Charge necesario para respaldar toda la vista con el archivo de paginación. ↩ ↩2 -
Microsoft Learn, Understanding Node Metrics and Properties in HPC Cluster Manager. Sobre que Available Physical Memory se calcula como la suma de las listas Zeroed, Free y Standby, y sobre el significado de cada una de esas listas de páginas. ↩
-
Microsoft Sysinternals, RAMMap. Sobre la función que analiza el uso de memoria física de Windows por uso, lista de páginas, proceso, prioridad, página física y archivo. ↩ ↩2
-
Microsoft Learn, Process.WorkingSet64 Property. Sobre que
WorkingSet64devuelve el Working Set del proceso en bytes y corresponde al contador de rendimiento Working Set de Process. ↩ -
Microsoft Learn, Process.PrivateMemorySize64 Property. Sobre que
PrivateMemorySize64devuelve la memoria propia del proceso que no puede compartirse con otros procesos, y corresponde al contador de rendimiento Private Bytes. ↩ -
Microsoft Learn, Process.VirtualMemorySize64 Property. Sobre que
VirtualMemorySize64devuelve la cantidad de memoria virtual del proceso y corresponde al contador de rendimiento Virtual Bytes. ↩ -
Microsoft Sysinternals, VMMap. Sobre la función que descompone por tipo la memoria virtual con Commit de un proceso y muestra la memoria física asignada a cada una (Working Set) junto con un mapa de memoria detallado. ↩ ↩2
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
Interioridades de la memoria de Windows (parte 2) — La vida de una página física: las cinco listas y la verdad del archivo de paginación
Conecta la base de datos PFN, Standby, Modified, la compresión de memoria y el archivo de paginación, y explica adónde va una página físi...
Aplicaciones que se rompen al reanudar de la suspensión — Eventos de energía y aplicaciones empresariales que sobreviven a la reanudación
Abre el portátil y las conexiones de la aplicación empresarial están cortadas: la causa es un diseño que no contempló la suspensión. Este...
DllMain y el bloqueo del cargador — La razón real de que le digan «no haga nada en la inicialización de la DLL»
Por qué no debe llamar a LoadLibrary ni sincronizar con otros hilos desde DllMain. A partir de fuentes primarias, este artículo explica e...
Qué es realmente «No responde» — Cómo decide Windows que una aplicación se ha colgado, y cómo diseñar aplicaciones que no lo hagan
«No responde» de Windows es un mecanismo en el que el sistema operativo juzga que una ventana no ha recuperado un mensaje durante 5 segun...
Cómo interpretar los códigos de error de Windows — la estructura de tres capas de Win32, HRESULT y NTSTATUS
Si aparece 0x80004005, descompóngalo antes de buscar. La estructura de tres capas de Win32, HRESULT y NTSTATUS, el patrón 0x8007xxxx y có...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Investigación de fallos y problemas prolongados
Fallos intermitentes, diagnóstico de comunicaciones, bloqueos prolongados y pruebas de rutas de error.
Servicios relacionados con este tema
El artículo está directamente relacionado con los siguientes servicios.
Desarrollo de aplicaciones para Windows
Aplicaciones empresariales, integración de dispositivos y herramientas de comunicación, de los requisitos al desarrollo.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿La «Memoria» del Administrador de tareas es toda la memoria que la aplicación tiene reservada?
- No. El Administrador de tareas tiene varias columnas de memoria —la familia Working Set, la familia Private Working Set, Commit Size, entre otras— y el significado cambia según la pantalla y la columna que se mire. Working Set es la cantidad de páginas actualmente cargadas en RAM; Private Bytes o Commit Size es la cantidad de Commit propia de ese proceso. No interprete una sola columna de «memoria» como la capacidad total reservada por la aplicación ni como la magnitud de una fuga.
- ¿En qué se diferencian Working Set y Private Bytes?
- Working Set es la cantidad de páginas visibles para ese proceso que están actualmente residentes en la RAM física, e incluye páginas compartidas como el código de DLL o archivos mapeados en memoria. Private Bytes es la cantidad de memoria con Commit que usa exclusivamente ese proceso, sin importar si está residente en RAM en este momento. Por lo tanto, ambos valores no coinciden y ni siquiera guardan una relación simple de mayor o menor.
- ¿«Comprometido 18/32 GB» en el Administrador de tareas significa que se han escrito 18 GB en el archivo de paginación?
- No es así. El lado izquierdo es la cantidad de Commit que todo el sistema tiene actualmente prometida, y el lado derecho es el límite de Commit que el sistema puede sostener. Ese límite se determina, a grandes rasgos, por la suma de la RAM y el archivo de paginación, pero no todo el total del lado izquierdo está en el archivo de paginación. Muchas páginas con Commit están en la RAM, y algunas páginas con Commit todavía no han recibido nunca una página física. Por otro lado, las páginas que pueden volver a cargarse desde el archivo original, como EXE, DLL o archivos mapeados en memoria, no siempre aumentan el Commit privado en la misma medida que aumentan el Working Set.
- ¿Puede producirse un OutOfMemory aunque haya RAM libre?
- Sí, puede ocurrir. Existen condiciones de fallo de asignación distintas de la RAM física: falta de espacio de direcciones virtuales en un proceso de 32 bits, falta de un rango continuo de direcciones libres, el límite de Commit del sistema, o límites propios de un Job Object o del runtime, entre otras. En particular, un proceso de 32 bits en Windows de 64 bits que no sea Large Address Aware tiene normalmente un límite de 2 GB de espacio de direcciones virtuales en modo usuario.
- ¿Deshabilitar el archivo de paginación hace que Windows vaya más rápido?
- En general, no se puede dar por hecho que vaya a ir más rápido. Deshabilitar el archivo de paginación reduce el límite de Commit del sistema, dificulta retirar de la RAM las páginas modificadas que no se están usando, y también afecta a la configuración del volcado de memoria en caso de fallo. El tamaño del archivo de paginación debe decidirse midiendo el Commit en el pico de uso y el volcado de memoria que se necesite, y no es una opción que deba deshabilitarse sin fundamento.
- ¿Un Page Faults/sec elevado significa falta de memoria?
- Con ese dato solo no se puede juzgar. Los Page Fault incluyen fallos blandos, que se resuelven con páginas Standby en RAM o compartidas con otro proceso, y fallos duros, que requieren leer desde disco. No se fije solo en Page Faults/sec: revise en el mismo eje temporal Pages Input/sec, Page Reads/sec, Available MBytes, la latencia de disco y el tiempo de procesamiento.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.