Depuración de un volcado de memoria administrada con analizadores de diagnóstico de .NET

En este tutorial, aprenderá lo siguiente:

  • Abrir un volcado de memoria
  • Seleccionar y ejecutar analizadores en el volcado
  • Revisar los resultados de los analizadores
  • Navegar al código problemático

En el ejemplo descrito en este artículo, el problema es que la aplicación no responde a las solicitudes de forma oportuna.

Apertura de un volcado de memoria en Visual Studio

  1. Abra el volcado de memoria en Visual Studio mediante el comando de menú Archivo > Abrir > Archivo y seleccione el volcado de memoria.

  2. Observe en la página de resumen del volcado de memoria una nueva acción denominada Run Diagnostics Analysis (Ejecutar análisis de diagnóstico).

    Action - Diagnostics Analysis

  3. Seleccione esta acción para iniciar el depurador y abrir la nueva página Diagnostic Analysis (Análisis de diagnóstico) con una lista de opciones de analizador disponibles, organizadas según el síntoma subyacente.

Selección y ejecución de analizadores en el volcado

Para investigar estos síntomas, las mejores opciones están disponibles en Process Responsiveness (Capacidad de respuesta del proceso), ya que coincide mejor con el problema de este ejemplo.

Select diagnostics analyzers

  1. Haga clic en el botón Analyze (Analizar) para iniciar el proceso de investigación.

  2. El analizador presentará resultados basados en la combinación de información de proceso y datos de CLR capturados en el volcado de memoria.

Revisión de los resultados de los analizadores

  1. En este caso, el analizador ha encontrado dos errores. Seleccione el resultado del analizador para ver el resumen de análisis y la corrección sugerida.

    Diagnostics analyzers results

  2. En el resumen de análisis se indica que "El grupo de subprocesos de CLR está experimentando un colapso". Esta información sugiere que CLR ha usado actualmente todos los subprocesos del grupo de subprocesos disponibles, lo que significa que el servicio no puede responder a ninguna solicitud nueva hasta que se libere un subproceso.

    Nota

    La corrección en este caso es "Do not synchronously wait on Monitors, Events, Task, or any other objects that may block your thread. See if you can update the method to be asynchronous." (No esperar sincrónicamente en monitores, eventos, tareas o cualquier otro objeto que pueda bloquear el subproceso. Vea si puede actualizar el método para que sea asincrónico").

Mi siguiente trabajo es buscar ese código problemático.

  1. Al hacer clic en el vínculo Mostrar pila de llamadas, Visual Studio cambiará inmediatamente a los subprocesos que presentan este comportamiento.

  2. En la ventana Pila de llamadas se mostrarán los métodos que pueden distinguir rápidamente entre mi código (SyncOverAsyncExmple. ) y el código de Framework (System. ).

    Diagnostics analyzers link to call stack

  3. Cada marco de pila de llamadas corresponde a un método y, al hacer doble clic en los marcos de pila, Visual Studio navegará hasta el código que remitió directamente a este escenario en este subproceso.

  4. En este ejemplo, no hay símbolos ni código, pero en la página Símbolos no cargados puede seleccionar la opción Descompilar código fuente .

    Decompilation

  5. En el origen descompilado siguiente, es evidente que una tarea asincrónica (ConsumeThreadPoolThread) llama a una función de bloqueo sincrónica.

    Nota

    El método "DoSomething()" que contiene un método WaitHandle.WaitOne, que bloquea el subproceso del grupo de subprocesos actual hasta que recibe una señal.

    Para mejorar la capacidad de respuesta de las aplicaciones, es importante quitar el código sincrónico de bloqueo de todos los contextos asincrónicos.

    Analyze decompiled code