debugging que - ¿Qué son los bytes privados, los bytes virtuales, el conjunto de trabajo?




kilobyte diferencia (5)

Estoy tratando de usar la utilidad perfmon windows para depurar las pérdidas de memoria en un proceso.

Así es como perfmon explica los términos:

Conjunto de trabajo es el tamaño actual, en bytes, del Conjunto de trabajo de este proceso. El conjunto de trabajo es el conjunto de páginas de memoria tocadas recientemente por los hilos en el proceso. Si la memoria libre en la computadora está por encima de un umbral, las páginas se dejan en el Conjunto de trabajo de un proceso, incluso si no están en uso. Cuando la memoria libre cae por debajo de un umbral, las páginas se recortan de los Conjuntos de trabajo. Si son necesarios, serán devueltos por error al Conjunto de Trabajo antes de salir de la memoria principal.

Los bytes virtuales son el tamaño actual, en bytes, del espacio de direcciones virtuales que utiliza el proceso. El uso del espacio de direcciones virtuales no implica necesariamente el uso correspondiente de las páginas del disco o de la memoria principal. El espacio virtual es finito, y el proceso puede limitar su capacidad para cargar bibliotecas.

Bytes privados es el tamaño actual, en bytes, de la memoria que este proceso ha asignado y que no se puede compartir con otros procesos.

Estas son las preguntas que tengo:

¿Son los bytes privados los que debo medir para asegurarme de que el proceso tenga fugas, ya que no involucra bibliotecas compartidas y que las fugas, si ocurren, provendrán del proceso en sí?

¿Cuál es la memoria total consumida por el proceso? ¿Son los bytes virtuales o es la suma de los bytes virtuales y el conjunto de trabajo?

¿Existe alguna relación entre los bytes privados, el conjunto de trabajo y los bytes virtuales?

¿Existen otras herramientas que den una mejor idea del uso de la memoria?


Answers

La definición de los contadores de perfmon se ha roto desde el principio y por alguna razón parece ser demasiado difícil de corregir.

En el video " Misterios de la administración de memoria revelada " en MSDN, se encuentra disponible una buena descripción general de la administración de memoria de Windows: Cubre más temas de los necesarios para realizar un seguimiento de las fugas de memoria (por ejemplo, administración de conjuntos de trabajo), pero brinda suficiente información detallada sobre los temas relevantes.

Para darle una pista del problema con las descripciones de los contadores de rendimiento, aquí está la historia interna sobre bytes privados del " Contador de rendimiento de bytes privados - ¡Cuidado! " En MSDN:

P: ¿Cuándo un byte privado no es un byte privado?

A: Cuando no es residente.

El contador de bytes privados informa el cargo de confirmación del proceso. Es decir, la cantidad de espacio que se ha asignado en el archivo de intercambio para almacenar los contenidos de la memoria privada en caso de que se intercambie. Nota: estoy evitando la palabra "reservado" debido a una posible confusión con la memoria virtual en el estado reservado que no se ha confirmado.

De " Planificación de rendimiento " en MSDN:

3.3 Bytes privados

3.3.1 Descripción

La memoria privada se define como la memoria asignada para un proceso que no puede ser compartida por otros procesos. Esta memoria es más cara que la memoria compartida cuando se ejecutan varios de estos procesos en una máquina. La memoria privada en las dll no administradas (tradicionales) usualmente se compone de estadísticas C ++ y es del orden del 5% del conjunto de trabajo total de la dll.


La respuesta corta a esta pregunta es que ninguno de estos valores es un indicador confiable de cuánta memoria está utilizando realmente el ejecutable, y ninguno de ellos es realmente apropiado para depurar una pérdida de memoria.

Los bytes privados se refieren a la cantidad de memoria que el proceso ejecutable ha solicitado , no necesariamente la cantidad que realmente está utilizando . Son "privados" porque (generalmente) excluyen archivos asignados en memoria (es decir, DLL compartidas). Pero, aquí está el problema, no necesariamente excluyen la memoria asignada por esos archivos . No hay forma de saber si un cambio en los bytes privados se debió al ejecutable mismo o a una biblioteca vinculada. Los bytes privados tampoco son exclusivamente memoria física; se pueden ubicar en el disco o en la lista de páginas en espera (es decir, ya no están en uso, pero tampoco están paginados).

Conjunto de trabajo se refiere a la memoria física total (RAM) utilizada por el proceso. Sin embargo, a diferencia de los bytes privados, esto también incluye archivos asignados en memoria y otros recursos, por lo que es una medida aún menos precisa que los bytes privados. Este es el mismo valor que se informa en el "Uso de memoria" del Administrador de tareas y ha sido fuente de infinitas confusiones en los últimos años. La memoria en el conjunto de trabajo es "física" en el sentido de que puede direccionarse sin un error de página; sin embargo, la lista de páginas en espera también se encuentra físicamente en la memoria pero no se informa en el conjunto de trabajo, y es por esto que es posible que vea que el "Uso de Mem" cae repentinamente cuando minimiza una aplicación.

Los bytes virtuales son el espacio total de direcciones virtuales ocupado por todo el proceso. Esto es como el conjunto de trabajo, en el sentido de que incluye archivos asignados en memoria (DLL compartidos), pero también incluye datos en la lista de espera y datos que ya se han extraído y se encuentran en un archivo de paginación en el disco en algún lugar. El total de bytes virtuales utilizados por cada proceso en un sistema con una gran carga sumará significativamente más memoria de la que realmente tiene la máquina.

Así que las relaciones son:

  • Los bytes privados son lo que su aplicación realmente ha asignado, pero incluyen el uso del archivo de paginación;
  • Working Set son los bytes privados no paginados más los archivos asignados en memoria;
  • Los bytes virtuales son el conjunto de trabajo más los bytes privados paginados y la lista de espera.

Hay otro problema aquí; así como las bibliotecas compartidas pueden asignar memoria dentro de su módulo de aplicación, lo que puede generar falsos positivos en los Bytes privados de su aplicación, su aplicación también puede terminar asignando memoria dentro de los módulos compartidos , lo que lleva a falsos negativos . Eso significa que en realidad es posible que su aplicación tenga una pérdida de memoria que nunca se manifiesta en los Bytes privados. Improbable, pero posible.

Los bytes privados son una aproximación razonable de la cantidad de memoria que utiliza su ejecutable y pueden usarse para ayudar a reducir una lista de posibles candidatos para una pérdida de memoria; Si ve que el número crece y crece de manera constante e interminable, querrá verificar que el proceso no tenga fugas. Esto no puede, sin embargo, probar que hay o no una fuga.

Una de las herramientas más efectivas para detectar / corregir las pérdidas de memoria en Windows es en realidad Visual Studio (el enlace va a la página sobre el uso de VS para las pérdidas de memoria, no la página del producto). La purificación racional es otra posibilidad. Microsoft también tiene un documento de mejores prácticas más general sobre este tema. Hay más herramientas enumeradas en esta pregunta anterior .

Espero que esto aclare algunas cosas! Rastrear las pérdidas de memoria es una de las cosas más difíciles de hacer en la depuración. Buena suerte.


Hay una discusión interesante aquí: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Mi comprensión de este hilo es que liberar pequeñas asignaciones es no se refleja en los bytes privados o conjunto de trabajo.

Larga historia corta:

si llamo

p=malloc(1000);
free(p);

entonces los bytes privados reflejan solo la asignación, no la desasignación.

si llamo

p=malloc(>512k);
free(p);

entonces los bytes privados reflejan correctamente la asignación y la desasignación.


No debe intentar usar perfmon, el administrador de tareas ni ninguna otra herramienta similar para determinar las pérdidas de memoria. Son buenos para identificar tendencias, pero no mucho más. Los números que informan en términos absolutos son demasiado vagos y se agregan para ser útiles para una tarea específica, como la detección de fugas de memoria.

Una respuesta previa a esta pregunta ha dado una gran explicación de cuáles son los distintos tipos.

Pregunta por una recomendación de herramienta: recomiendo Memory Validator. Capaz de monitorear aplicaciones que hacen miles de millones de asignaciones de memoria.

http://www.softwareverify.com/cpp/memory/index.html

Descargo de responsabilidad: He diseñado Memory Validator.


Para completar la respuesta aceptada de BlueM, puede desactivarla aquí:

Herramientas> Opciones> Depuración> Configuración de salida general> Mensajes de salida de subproceso: desactivado





debugging memory-leaks operating-system memory-management