Medición del uso de memoria en Visual Studio (C#, Visual Basic, C++, F#)
Busque pérdidas de memoria y memoria ineficaz durante la depuración con la herramienta de diagnóstico Uso de memoria integrada del depurador. La herramienta Uso de memoria permite tomar una o más instantáneas del montón de memoria nativa y administrada para que pueda conocer el impacto del uso de memoria de los tipos de objeto. También puede analizar el uso de memoria sin un depurador asociado o tener como destino una aplicación en ejecución. Para obtener más información, consulte Ejecución de herramientas de generación de perfiles en compilaciones de versión o depuración. Para obtener información sobre cómo elegir la mejor herramienta de análisis de memoria para sus necesidades, consulte Elegir una herramienta de análisis de memoria.
Aunque puede recopilar instantáneas de memoria en cualquier momento en la herramienta Uso de memoria, puede usar el depurador de Visual Studio para controlar cómo se ejecuta su aplicación mientras investiga problemas de rendimiento. Las acciones del depurador como establecer puntos de interrupción, ejecutar paso a paso e interrumpir todos, entre otras, pueden ayudarle a centrarse en las investigaciones de rendimiento en las rutas de acceso de código que son más importantes. Realizar esas acciones mientras se ejecuta la aplicación puede eliminar el ruido del código que no le interesa y puede reducir significativamente la cantidad de tiempo que tarda en diagnosticar un problema.
Importante
Las herramientas de diagnóstico integradas del depurador están disponibles para el desarrollo de .NET en Visual Studio, incluyendo ASP.NET, ASP.NET Core, el desarrollo nativo/C++ y las aplicaciones de modo mixto (.NET y nativo).
En este tutorial, hará lo siguiente:
- Tomar instantáneas de la memoria
- Análisis de datos de uso de memoria
Si el uso de memoria de no le proporciona los datos que necesita, otras herramientas de análisis en el Generador de perfiles de rendimiento ofrecen diferentes tipos de información que podrían resultarle útiles. En muchos casos, el cuello de botella de rendimiento de la aplicación puede no ser debido a la memoria sino a la CPU, la representación de interfaz de usuario o el tiempo de solicitud de red.
Nota
Compatibilidad con el asignador personalizado El generador de perfiles de memoria nativa funciona mediante la recopilación de datos de asignación de eventos de ETW que se emiten en tiempo de ejecución. Los asignadores de CRT y Windows SDK se han anotado en el nivel de origen para que se pueden capturar los datos de asignación. Si escribe sus propios asignadores, las funciones que devuelven un puntero a la memoria de montón recientemente asignada se pueden decorar con __declspec(allocator), tal como se muestra en este ejemplo para myMalloc:
__declspec(allocator) void* myMalloc(size_t size)
Recopilación de datos de uso de memoria
Abra el proyecto que desea depurar en Visual Studio y establezca un punto de interrupción en la aplicación en el punto en el que desea empezar a examinar el uso de memoria.
Si tiene un área en la que sospecha un problema de memoria, establezca el primer punto de interrupción antes de que se produzca el problema de memoria.
Sugerencia
Dado que puede resultar difícil capturar el perfil de memoria de una operación que le interese cuando la aplicación asigna y desasigna memoria con frecuencia, establezca puntos de interrupción al principio y al final de la operación (o recorra la operación) para encontrar el punto exacto que cambió la memoria.
Establezca un segundo punto de interrupción al final de la función o región del código que desea analizar (o después de que se produzca un problema de memoria sospechoso).
La ventana Herramientas de diagnóstico aparece automáticamente a menos que la haya desactivado. Para que la ventana se vuelva a mostrar, haga clic en Depurar>Windows>Mostrar Herramientas de diagnóstico.
Elija Uso de memoria con la opción Seleccionar herramientas en la barra de herramientas.
Haga clic en Depurar / Iniciar depuración (o Iniciar en la barra de herramientas, o F5).
Cuando la aplicación termine de cargarse, aparece la vista Resumen de las herramientas de diagnóstico.
Nota
Dado que la recopilación de datos de memoria puede afectar al rendimiento de depuración de las aplicaciones nativas o en modo mixto, las instantáneas de memoria están deshabilitadas de forma predeterminada. Para habilitar instantáneas en aplicaciones nativas o en modo mixto, inicie una sesión de depuración (tecla de acceso rápido: F5). Cuando aparezca la ventana Herramientas de diagnóstico, seleccione la pestaña Uso de memoria y luego elija Generación de perfiles de montón.
Detenga la depuración (tecla de método abreviado: Mayús+F5) y reiníciela.
Nota
Dado que la recopilación de datos de memoria puede afectar al rendimiento de depuración de las aplicaciones nativas o en modo mixto, las instantáneas de memoria están deshabilitadas de forma predeterminada. Para habilitar instantáneas en aplicaciones nativas o en modo mixto, inicie una sesión de depuración (tecla de acceso rápido: F5). Cuando aparezca la ventana Herramientas de diagnóstico, seleccione la pestaña Uso de memoria y luego elija Generación de perfiles de montón.
Detenga la depuración (tecla de método abreviado: Mayús+F5) y reiníciela.
Para tomar una instantánea al comienzo de la sesión de depuración, elija Instantánea en la barra de herramientas reducida Uso de memoria. (También puede ayudar a establecer un punto de interrupción aquí).
Sugerencia
Para crear una línea base para comparaciones de memoria, considere la posibilidad de tomar una instantánea al principio de la sesión de depuración.
Ejecute el escenario que hará que se alcance el primer punto de interrupción.
Mientras el depurador está en pausa en el primer punto de interrupción, elija Instantánea en la barra de herramientas reducida Uso de memoria.
Presione F5 para ejecutar la aplicación hasta su segundo punto de interrupción.
Ahora, tome otra instantánea.
En este momento, puede empezar a analizar los datos.
Si tiene problemas para recopilar o mostrar datos, consulte Solución de problemas de generación de perfiles y corrección de problemas.
Análisis de datos de uso de memoria
Las filas de la tabla de resumen de uso de memoria enumeran las instantáneas que ha tomado durante la sesión de depuración y proporcionan vínculos a vistas más detalladas.
El nombre de la columna depende del modo de depuración que elija en las propiedades del proyecto: .NET, nativo o mixto (tanto .NET como nativo).
La columna Objetos (diferencias) (.NET) o Asignaciones (diferencias) (C++) muestra el número de objetos en .NET o en memoria nativa cuando se tomó la instantánea.
La columna Tamaño de montón (dif.) muestra el número de bytes en los montones .NET y nativos.
Cuando haya tomado varias instantáneas, las celdas de la tabla de resumen incluyen el cambio en el valor entre la instantánea de fila y la instantánea anterior.
Para analizar el uso de memoria, haga clic en uno de los vínculos que abre un informe detallado de uso de memoria:
- Para ver los detalles de la diferencia entre la instantánea actual y la instantánea anterior, elija el vínculo cambiar a la izquierda de la flecha (). Una flecha roja indica un aumento en el uso de memoria y una flecha verde indica una disminución.
Sugerencia
Para ayudar a identificar los problemas de memoria más rápidamente, los informes de diferencias se ordenan por tipos de objeto que aumentaron más en el número total (haga clic en el enlace de cambio en la columna Objetos (Diferencia)) o que aumentaron más en el tamaño total del montón (haga clic en el enlace de cambio en la columna Tamaño del Montón (Diferencia)).
Para ver los detalles de solo la instantánea seleccionada, haga clic en el vínculo no modificado.
El informe aparece en una ventana independiente.
Informes de tipos administrados
Elija el vínculo actual de la celda Objects (diferencias) en la tabla resumen de Uso de memoria.
Nota
En el caso del código .NET, el icono Ver instancias () solo está disponible mientras se usa la herramienta de uso de memoria integrada del depurador o cuando se abre una instantánea de montón y se elige Depurar memoria administrada.
El panel superior muestra el número y el tamaño de los tipos en la instantánea, incluido el tamaño de todos los objetos a los que hace referencia el tipo (Tamaño inclusivo).
El árbol Rutas de acceso a la raíz del panel inferior muestra los objetos que hacen referencia al tipo seleccionado en el panel superior. El recolector de elementos no utilizados de .NET limpia la memoria de un objeto únicamente si el último tipo que hace referencia a este se ha liberado. Para obtener más información sobre el uso del árbol Rutas a la raíz, consulte Análisis de la ruta de acceso activa a la raíz.
El panel superior muestra el número y el tamaño de los tipos en la instantánea, incluido el tamaño de todos los objetos a los que hace referencia el tipo (Tamaño inclusivo).
El árbol Rutas de acceso a la raíz del panel inferior muestra los objetos que hacen referencia al tipo seleccionado en el panel superior. El recolector de elementos no utilizados de .NET limpia la memoria de un objeto únicamente si el último tipo que hace referencia a este se ha liberado.
El árbol Tipos a los que se hace referencia muestra las referencias que se incluyen en el tipo seleccionado en el panel superior.
El árbol Tipos a los que se hace referencia muestra las referencias que se incluyen en el tipo seleccionado en el panel superior.
Para mostrar las instancias de un tipo seleccionado en el panel superior, haga clic en el icono Ver instancias junto al tipo de objeto.
La vista Instancias muestra las instancias del objeto seleccionado en la instantánea en el panel superior. El panel Rutas a la raíz y Objetos referenciados muestra los objetos que hacen referencia a la instancia seleccionada y los tipos a los que hace referencia la instancia seleccionada. Cuando el depurador se detiene en el punto donde se tomó la instantánea, puede desplazar el puntero sobre la celda Valor para mostrar los valores del objeto en la información sobre herramientas.
La vista Instancias muestra las instancias del objeto seleccionado en la instantánea en el panel superior. Los paneles Rutas de acceso al nodo raíz y Objetos a los que se hace referencia muestran los objetos que hacen referencia a la instancia seleccionada y los tipos a los que hace referencia la instancia seleccionada. Cuando el depurador se detiene en el punto donde se tomó la instantánea, puede desplazar el puntero sobre la celda Valor para mostrar los valores del objeto en la información sobre herramientas.
Informes de tipos nativos
Elija el vínculo actual de una celda Asignaciones (dif.) o Tamaño de montón (dif.) en la tabla de resumen Uso de memoria de la ventana Herramientas de diagnóstico.
La vista de tipos muestra el número y el tamaño de los tipos en la instantánea.
Elija el icono Ver instancias junto a un tipo seleccionado para mostrar información sobre los objetos del tipo seleccionado en la instantánea.
La vista de instancias muestra cada instancia del tipo seleccionado. Al seleccionar una instancia se muestra la pila de llamadas que produjo la creación de la instancia en el panel Pila de llamadas de asignación. Esta información solo está disponible durante la depuración.
Elija el icono de instancias () de un tipo seleccionado para mostrar información sobre los objetos del tipo seleccionado en la instantánea.
La vista Instancias muestra cada instancia del tipo seleccionado. Al seleccionar una instancia se muestra la pila de llamadas que produjo la creación de la instancia en el panel Pila de llamadas de asignación.
Elija Vista de pilas en la lista Modo de vista para ver la pila de asignación del tipo seleccionado.
Información de uso de memoria
Para la memoria administrada, la herramienta Análisis de memoria también proporciona varias conclusiones automáticas integradas eficaces. Seleccione la pestaña Información en los informes de tipos administrados y se mostrará la información automática aplicable, como Cadenas duplicadas, Matrices dispersas y Pérdidas del controlador de eventos.
La sección Cadenas duplicadas muestra la lista de cadenas que se asignan varias veces en el montón. Además, en esta sección se muestra la cantidad total de memoria desperdiciada, es decir, (el número de instancias - 1) multiplicado por el tamaño de la cadena.
La sección matrices dispersas muestra matrices que se rellenan principalmente con cero elementos, lo que puede ser ineficaz en términos de rendimiento y uso de memoria. La herramienta de análisis de memoria detectará automáticamente estas matrices y mostrará la cantidad de memoria que se está desperdiciando debido a estos valores cero.
La sección Pérdidas del controlador de eventos, disponible en Visual Studio 2022, versión 17.9, versión preliminar 1, muestra posibles pérdidas de memoria que pueden producirse cuando un objeto se suscribe al evento de otro. Si el publicador del evento sobrevive al suscriptor, el suscriptor permanece activo, incluso si no hay otras referencias a él. Esto puede provocar pérdidas de memoria, donde la memoria no utilizada no está libre correctamente, lo que hace que la aplicación use más y más memoria a lo largo del tiempo.
Se sabe que ciertos tipos tienen campos que se pueden leer para determinar el tamaño de la memoria nativa en la que se encuentran. En la pestaña Insights se muestran nodos de memoria nativa falsos en el gráfico de objetos, que sus objetos primarios conservan para que la interfaz de usuario los reconozca y muestre su tamaño y gráfico de referencia.
Informes de cambios (diferencias)
Elija el vínculo de cambio en una celda de la tabla de resumen de la pestaña Uso de Memoria en la ventana Herramientas de Diagnóstico.
Elija una instantánea de la lista Comparar con en un informe administrado o nativo.
El informe de cambios agrega columnas (marcadas con (Diff)) al informe base que muestran la diferencia entre el valor de la instantánea base y la instantánea de comparación. Este es el aspecto de un informe de diferencias de la vista de tipo nativo:
El panel superior muestra el número y el tamaño de los tipos en la instantánea, incluido el tamaño de todos los objetos a los que hace referencia el tipo (Tamaño inclusivo).
Blogs y vídeos
Analyze CPU and Memory While Debugging (Análisis de la CPU y la memoria durante la depuración)
blog de Visual C++: Generación de perfiles de memoria en Visual C++ 2015
Pasos siguientes
En este tutorial, ha aprendido a recopilar y analizar datos de uso de memoria. Si ya completó el recorrido del generador de perfiles, es posible que quiera leer sobre un enfoque general para optimizar el código mediante las herramientas de generación de perfiles.
En este tutorial, ha aprendido cómo recopilar y analizar los datos de uso de la memoria durante la depuración. Es posible que quiera obtener más información sobre el análisis del uso de memoria en las compilaciones de versión mediante el Generador de perfiles de rendimiento.