Compartir a través de


Información general sobre problemas de consumo elevado de memoria

En esta guía de solución de problemas se proporcionan pasos para diagnosticar y resolver problemas de consumo elevado de memoria en las aplicaciones, centrándose en escenarios que implican pérdidas de memoria. Le ayuda a comprender los síntomas típicos, los límites relacionados con el uso de memoria en diferentes configuraciones del sistema y las herramientas necesarias para diagnosticar el problema de forma eficaz.

Herramientas de captura de datos

Nota:

  • Evite usar el Administrador de tareas para recopilar volcados de memoria. Las herramientas especializadas, como DebugDiag y Procdump, son más eficaces para ASP.NET aplicaciones a medida que comprenden mejor el código administrado y controlan automáticamente el bits del proceso.
  • Es posible que se necesiten varios intentos para obtener un conjunto útil de volcados de memoria.
  • Asegúrese de tener suficiente espacio en disco para volcados de memoria. Cada volcado es aproximadamente el tamaño del proceso en ese momento. Por ejemplo, si el proceso es de 1 gigabyte (GB), la generación de tres volcados requiere aproximadamente 4 GB de espacio.

Límites de memoria para distintos escenarios

Las pérdidas de memoria suelen dar lugar a un aumento constante del uso de memoria, lo que provoca bloqueos o degradación del rendimiento:

Nota:

El uso elevado de memoria no siempre indica una fuga; Los procesos pueden recuperarse si la memoria asignada se libera más adelante. Una pérdida de memoria se debe a uno o varios errores en la aplicación donde las asignaciones nunca se liberan.

  • Aplicaciones de 32 bits: las aplicaciones de 32 bits pueden bloquearse y producir una OutOfMemory excepción al quedarse sin memoria, posiblemente sin notificar errores antes de bloquearse. Pueden comportarse de forma imprevisible si los errores de asignación de memoria no se controlan correctamente en el código de la aplicación.
  • Aplicaciones de 64 bits: las aplicaciones de 64 bits rara vez producen un error al intentar asignar memoria virtual debido al espacio de direcciones grande. Sin embargo, pueden crecer para tener un espacio de direcciones virtual muy grande y provocar una paginación excesiva de memoria física, lo que afecta a la aplicación y otras aplicaciones que compiten por la memoria física.
Escenario Límite de memoria Más información
Aplicaciones de 32 bits en Windows de 32 bits 4 GB en total (2 GB en modo de usuario, 2 GB en modo kernel) Si usa la marca /LARGEADDRESSAWARE en las aplicaciones de 32 bits y el modificador /3GB en el archivo boot.ini del sistema operativo durante el tiempo de arranque, hace que el modo de usuario sea de 3 GB y el modo kernel 1 GB.
Aplicaciones de 32 bits en Windows de 64 bits 4 GB en total (2 GB en modo de usuario, 2 GB en modo kernel) Si usa la marca /LARGEADDRESSAWARE en las aplicaciones de 32 bits, hace que la memoria en modo de usuario sea de 4 GB. El kernel no usa el espacio de direcciones de 32 bits en un sistema operativo de 64 bits. Usa solo el espacio necesario del espacio de direcciones de 64 bits.
Aplicaciones de 64 bits en Windows de 64 bits 2^64 bytes = 16 Exabyte (EB) (~100 Crore GB). Sin embargo, Windows10 x 64 admite 48 bits de dirección virtual: 2^48 bytes = 256 TB (128 TB en modo de usuario, 128 TB en modo kernel). N/D
Aplicaciones de 64 bits en Windows de 32 bits Escenario no válido N/D

Identificación del uso elevado de memoria

La manera más sencilla de identificar el uso elevado de memoria es supervisar el contador Bytes privados (KB) mediante el módulo Procesos de trabajo del Administrador de Internet Information Services (IIS). El contador Bytes privados (KB) indica la cantidad de memoria confirmada privada que usa un proceso.

Para supervisar bytes privados (KB), siga estos pasos:

  1. Abra administrador de IIS.

  2. Seleccione el nombre del servidor (a la izquierda).

  3. Haga doble clic en Procesos de trabajo.

  4. Compruebe Bytes privados (KB). A continuación se muestra una captura de pantalla:

    Captura de pantalla de procesos de trabajo en la que se resalta la columna Bytes privados (KB).

    Si el valor bytes privados (KB) del proceso de w3wp.exe (proceso de trabajo de IIS) alcanza el límite de memoria tal como se describe en Límites de memoria para distintos escenarios, el proceso de w3wp.exe tiene un problema de memoria elevado. El identificador de proceso y el nombre del grupo de aplicaciones se muestran junto a él. Es posible que tenga que actualizar esta vista manualmente.

Identificar si la pérdida de memoria se administra o es nativa

Una vez que haya confirmado que el proceso de w3wp.exe está experimentando un uso elevado de memoria, el siguiente paso es identificar si se trata de una pérdida de memoria administrada o nativa. Siga estos pasos para identificar el tipo de pérdida de memoria:

  1. Abra Monitor de rendimiento y seleccione el + icono para agregar contadores.

    Captura de pantalla que resalta el icono más en Monitor de rendimiento.

  2. Seleccione # Bytes en todos los montones en el contador Memoria clR de .NET, seleccione el proceso de destino (aquí, es w3wp) y, a continuación, seleccione Agregar.

  3. Seleccione Bytes privados y bytes virtuales en el contador Proceso, seleccione el proceso de destino y, a continuación, seleccione Agregar (puede omitir el conjunto de trabajo).

    Captura de pantalla de la ventana Agregar contadores.

  4. Seleccione Aceptar.

  5. Reproduce el problema.

  6. Para comprobar si se trata de una pérdida de memoria administrada o nativa, supervise los contadores:

    • Pérdida de memoria administrada: si el contador Bytes privados y el contador Bytes virtuales aumentan a la misma velocidad (la diferencia entre ellos permanece constante), indica una pérdida de memoria administrada.

      Captura de pantalla que muestra cómo cambian los contadores para una pérdida de memoria administrada.

    • Pérdida de memoria nativa: si el contador Bytes privados aumenta, pero el contador # Bytes de todos los montones permanece constante, indica una pérdida de memoria nativa.

      Captura de pantalla que muestra cómo cambian los contadores para una pérdida de memoria nativa.

Recolección de datos

Una vez que haya confirmado el tipo de pérdida de memoria, el siguiente paso consiste en usar herramientas para recopilar volcados de memoria del proceso durante el evento de uso elevado de memoria. Estos volcados de memoria pueden ayudarle a analizar y diagnosticar la causa del problema.

Aplicaciones .NET Core

Si la aplicación en cuestión es .NET Core y se hospeda en IIS en modo en proceso, use los pasos de recopilación de datos en Captura de datos para pérdidas de memoria administradas. Sin embargo, si la aplicación se hospeda en IIS en modo fuera de proceso, modifique las acciones para investigar el proceso dotnet (dotnet.exe a menos que se especifique lo contrario) en lugar de w3wp.exe. Lo mismo se aplica a las aplicaciones de .NET Core autohospedado.

Ejemplo de solución de problemas

Supongamos que tiene una aplicación hospedada en un servidor IIS y experimenta un uso elevado de memoria (los picos de memoria hasta 7 GB al realizar una prueba de esfuerzo) al acceder a una dirección URL específica, siga estos pasos para diagnosticar el problema:

  1. Compruebe Monitor de rendimiento siguiendo los pasos descritos en Identificar si la pérdida de memoria se administra o es nativa. Si observa la diferencia entre bytes privados y bytes virtuales sigue siendo constante, se trata de una pérdida de memoria administrada.

  2. Recopile archivos de volcado siguiendo los pasos descritos en Uso de DebugDiag.

  3. Abra los archivos de volcado en WinDbg. Para escenarios de memoria elevada, puede usar los siguientes comandos:

    Get-Help Uso
    !dumpheap -stat Este comando muestra todos los objetos del montón administrado y sus estadísticas. Puede personalizar la salida mediante los distintos modificadores de !dumpheap para centrarse en tipos específicos de objetos, tamaños o estados, lo que facilita el análisis del montón administrado e identificar problemas como pérdidas de memoria.
    !eeheap -gc Este comando se puede usar para obtener el tamaño del montón administrado.
    !threads Este comando ayuda a comprobar si hay subprocesos de finalizador que muestren todos los subprocesos administrados.
    !finalizequeue Este comando se usa para mostrar todos los objetos de la cola de finalización.
  4. Después de ejecutar !dumpheap -stat, verá que system.char[], system.Text.Stringbuildery BuggyBits.Models.Link consume la mayoría de los objetos del montón, con recuentos de 322 547, 322 408 y 320 031.

    Nota:

    BuggyBits es el nombre de la aplicación de ejemplo que se usa en este ejemplo. Es posible que vea el nombre de la aplicación u otro nombre de proceso que podría consumir objetos altos.

    7ff93da4a520      601       1,00,968 Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper 
    7ff93dbbe068    2,576       1,03,040 Microsoft.AspNetCore.Mvc.ViewFeatures.TemplateInfo 
    7ff93dcb56f8    1,202       1,05,776 Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput 
    7ff93dbff3f0    1,245       1,09,560 Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper<System.Object> 
    7ff93db563b8    1,258       1,10,640 System.Collections.Generic.KeyValuePair<System.Func<System.Object, System.Threading.Tasks.Task>, System.Object>[] 
    7ff93dd01268    4,720       1,13,280 Microsoft.AspNetCore.Html.HtmlContentBuilder 
    7ff93dd01b40    4,721       1,13,304 Microsoft.AspNetCore.Mvc.ViewFeatures.AttributeDictionary 
    7ff93da51af0    1,202       1,15,392 Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext 
    7ff93d230af0    5,013       1,20,312 System.Object 
    <<< omitting few to save space>>> 
    7ff93dbc4c38      644       1,85,472 AspNetCore.Views_Links_Index 
    7ff93dbc7b50      644       1,85,472 AspNetCore.Views__ViewStart 
    7ff93d55f218    4,722       1,88,880 Microsoft.AspNetCore.Routing.RouteValuesAddress 
    7ff93dbc6fa0      601       2,16,360 AspNetCore.Views_Shared__Layout 
    7ff93dd01738    4,720       2,26,560 Microsoft.AspNetCore.Mvc.Rendering.TagBuilder 
    7ff93d236618      990       2,28,360 System.Object[] 
    7ff93dade018      644       2,47,296 System.IO.Pipelines.Pipe 
    7ff93dad9da0      644       2,57,600 Microsoft.AspNetCore.HttpSys.Internal.RequestHeaders 
    7ff93dcf4de8    4,720       2,64,320 System.Linq.Enumerable+<OfTypeIterator>d__61<Microsoft.AspNetCore.Routing.RouteEndpoint> 
    7ff93dc9be58    3,711       2,68,368 Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBufferValue[][] 
    7ff93dce0188    4,723       3,02,272 Microsoft.AspNetCore.Mvc.Routing.UrlActionContext 
    7ff93dc9b4e0    9,540       3,05,280 Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBufferPage 
    7ff93dcb71d0    7,690       3,07,600 Microsoft.Extensions.Internal.CopyOnWriteDictionary<System.Object, System.Object> 
    7ff93dcbe430    4,752       3,33,440 Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBufferPage[] 
    7ff93dcb7fd8    8,880       3,55,200 Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute 
    7ff93dcb5110    5,925       3,79,200 System.Func<System.Threading.Tasks.Task> 
    7ff93db27c10    8,853       3,96,592 Microsoft.AspNetCore.Routing.RouteEndpoint[] 
    7ff93dad6a98      644       3,96,704 Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT<Microsoft.AspNetCore.Hosting.HostingApplication+Context> 
    7ff93dce6a08    4,722       4,15,472 Microsoft.AspNetCore.Routing.Tree.OutboundMatchResult[] 
    7ff93d4285d8    4,724       4,15,536 System.Collections.Generic.KeyValuePair<System.String, System.String>[] 
    7ff93dcbdea0   10,694       4,27,760 Microsoft.AspNetCore.Razor.TagHelpers.DefaultTagHelperContent 
    7ff93da559b0   10,097       5,65,432 Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBuffer 
    7ff93da46430    4,738       5,68,560 Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper 
    7ff93dbf5ea8   10,063       8,05,040 Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBufferTextWriter 
    7ff93d94ba98   21,439       8,57,560 Microsoft.AspNetCore.Routing.RouteValueDictionary 
    7ff93daabd18   20,881      15,99,832 System.Collections.Generic.KeyValuePair<System.String, System.Object>[] 
    7ff93d2f2360      853      16,53,045 System.Byte[]  
    7ff93d2f1e18   23,943      17,47,166 System.String 
    7ff93da40928 3,20,031    1,02,40,992 BuggyBits.Models.Link 
    7ff93d4b7dc0 3,22,408    1,54,75,584 System.Text.StringBuilder 
    017e072f9d90 4,25,254   52,07,33,840 Free 
    7ff93d333058 3,22,547 6,40,93,53,398 System.Char[] 
    Total 17,82,793 objects, 6,98,09,63,784 bytes
    
  5. Volcar las estadísticas de varios tamaños de char[] para averiguar si hay un patrón (se trata de un proceso de prueba y error, por lo que tiene que probar diferentes tamaños para determinar dónde se encuentran la mayor parte de las cadenas).

  6. Ejecute el comando !dumpheap -mt 7ff93d333058 para enumerar todos los objetos del montón administrado que tienen la dirección 7ff93d333058 de tabla de métodos (MT) especificada para System.Char[].

    Address           MT                   Size  
    017e076607a0     7ff93d333058         20,024  
    017e07665640     7ff93d333058         20,024  
    017e0766a4e0     7ff93d333058         20,024  
    017e0766f380     7ff93d333058         20,024  
    017e07674220     7ff93d333058         20,024  
    017e076790c0     7ff93d333058         20,024  
    017e0767df60     7ff93d333058         20,024  
    017e07682e00     7ff93d333058         20,024  
    017e07687ca0     7ff93d333058         20,024  
    017e0768cb40     7ff93d333058         20,024  
    017e076919e0     7ff93d333058         20,024  
    017e07696880     7ff93d333058         20,024  
    017e0769b720     7ff93d333058         20,024  
    017e076a05c0     7ff93d333058         20,024  
    017e076a5460     7ff93d333058         20,024  
    017e076aa300     7ff93d333058         20,024  
    017e076af1a0     7ff93d333058         20,024  
    017e076b4040     7ff93d333058         20,024  
    017e076b8ee0     7ff93d333058         20,024  
    017e076bdd80     7ff93d333058         20,024  
    017e076c2c20     7ff93d333058         20,024  
    017e076c7ac0     7ff93d333058         20,024  
    017e076cc960     7ff93d333058         20,024  
    017e076d1800     7ff93d333058         20,024  
    017e076d66a0     7ff93d333058         20,024  
    017e076db540     7ff93d333058         20,024  
    017e076e03e0     7ff93d333058         20,024  
    017e076e5280     7ff93d333058         20,024  
    017e076ea120     7ff93d333058         20,024  
    017e076eefc0     7ff93d333058         20,024  
    017e076f3e60     7ff93d333058         20,024  
    017e076f8d00     7ff93d333058         20,024  
    017e076fdba0     7ff93d333058         20,024  
    017e07702a40     7ff93d333058         20,024  
    017e077078e0     7ff93d333058         20,024  
    017e0770c780     7ff93d333058         20,024  
    017e07711620     7ff93d333058         20,024  
    017e077164c0     7ff93d333058         20,024  
    

    Puede ver que la mayoría de ellos tienen el mismo tamaño. Y puede ver las siguientes estadísticas:

    Statistics: 
    MT              Count      TotalSize           Class Name 
    7ff93d333058    55,862     1,11,21,80,222      System.Char[] 
    Total 55,862 objects, 1,11,21,80,222 bytes 
    
  7. Volcar algunos de ellos para averiguar lo que contienen.

    0:000> !do  017e9a469e08  
    Name:        System.Char[] 
    MethodTable: 00007ff93d333058 
    EEClass:     00007ff93d332fd8 
    Size:        20024(0x4e38) bytes 
    Array:       Rank 1, Number of elements 10000, Type Char (Print Array) 
    Content:     http://blogs.msdn.com/tom....................................................................................................... 
    Fields: 
    None 
    0:000> !do 017e9a464f10  
    Name:        System.Char[] 
    MethodTable: 00007ff93d333058 
    EEClass:     00007ff93d332fd8 
    Size:        20024(0x4e38) bytes 
    Array:       Rank 1, Number of elements 10000, Type Char (Print Array) 
    Content:     http://blogs.msdn.com/jamesche.................................................................................................. 
    Fields: 
    
  8. Ahora, debe saber por qué no se recopilan.

    Si se ejecuta gcroot en algunas de esas direcciones y ve una cola de finalizador:

    0:000> !gcroot 017e9a469e08 
    Finalizer Queue: 
    000001831657ced0 (finalizer root) 
           -> 017e9a469da0     BuggyBits.Models.Link  
           -> 017e9a469dc0     System.Text.StringBuilder  
           -> 017e9a469e08     System.Char[]
    
  9. Compruebe el subproceso del finalizador para ver lo que está haciendo.

    Ejecute !threads para enumerar todos los subprocesos y mostrar sus estados. Verá que el subproceso 42 tiene un finalizador:

    0:000> !threads 
    ThreadCount:      86 
    UnstartedThread:  0 
    BackgroundThread: 36 
    PendingThread:    0 
    DeadThread:       49 
    Hosted Runtime:   no 
                                                                                                                Lock   
     DBG   ID     OSID ThreadOBJ         State   GC Mode     GC Alloc Context                  Domain           Count Apt Exception 
      24    1     7f04 0000017E06A683A0  202a020 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     MTA  
      42    2     c588 0000017E06A435C0  202b220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     MTA (Finalizer)  
      44    3     ca94 0000017E06A45BA0  102a220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     MTA (Threadpool Worker)
    XXXX    4        0 0000017E06A448B0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
      45    6     7424 0000017E06A45550  8029220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     MTA (Threadpool Completion Port)  
      46    7     ad48 0000017E06A44F00  202b220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     MTA  
      19   11     c1a0 0000018315B92F90    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   13        0 0000018315B922F0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   15        0 0000018315B96EB0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   16        0 0000018315B92940  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   17        0 0000018315B93C30  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
      15   18     b878 0000018315B94280    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
      17   19     9960 0000018315B91000    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
      18   20     90cc 0000018315B90360    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   14        0 0000018315B935E0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   12        0 0000018315B948D0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX    5        0 0000018315B95570  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   21        0 0000018315B8FD10  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   22        0 0000018315B91650  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   23        0 0000018315B96210  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   24        0 0000018315B909B0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
      16   27      6bc 0000018315B95BC0    20220 Preemptive  00000180E160EEF0:00000180E160F250 0000017e06237220 0     Ukn  
      14   28     c284 0000018315B96860    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   29        0 0000017E06A461F0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   30        0 0000018315BC7E90  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   31        0 0000018315BC7840  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   32        0 0000018315BC6BA0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   34        0 0000018315BC6550  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   38        0 0000018315BC58B0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   39        0 0000018315BC84E0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   40        0 0000018315BC1990  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
       7   41     c4cc 0000018315BC5F00    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   42        0 0000018315BC1FE0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   43        0 0000018315BC2630  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   44        0 0000018315BC2C80  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
       9   48     b838 0000018315BC45C0    20220 Preemptive  0000017EE1D45B38:0000017EE1D45FD0 0000017e06237220 0     Ukn  
       5   49      a40 0000018315BC4C10    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   50        0 0000018315D0AA30  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   51        0 0000018315D06B10  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
    XXXX   52        0 0000018315D0C370  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
       8   53     7024 0000018315D05820    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   54        0 0000018315D077B0  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
      11   55     7068 0000018315D05E70    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
      10   56     c0ac 0000018315D090F0    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    XXXX   63        0 00000183158CA200  1039820 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn (Threadpool Worker)  
       4   64     83d0 00000183158CAEA0    20220 Preemptive  0000018121307DF8:0000018121307FD0 0000017e06237220 0     Ukn  
       6   65     beb4 0000018315894860    20220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
      48   66     cad4 0000018315D0B6D0    21220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
      49   67     94f8 0000018315D0A3E0    21220 Preemptive  0000000000000000:0000000000000000 0000017e06237220 0     Ukn  
    
  10. Volcar el subproceso 42 y comprobar la pila y, a continuación, verá buggybits.models.link llamar a thread.Sleep:

    0:042> k 
    *** WARNING: Unable to verify checksum for BuggyBits.dll 
    #  Child-SP          RetAddr               Call Site
    00 00000027`987ff4e8 00007ffa`98245683     ntdll!NtDelayExecution+0x14
    01 00000027`987ff4f0 00007ffa`9593993d     ntdll!RtlDelayExecution+0x43
    02 00000027`987ff520 00007ff9`9cce7404     KERNELBASE!SleepEx+0x7d
    03 (Inline Function) --------`--------     coreclr!EESleepEx+0xd
    04 00000027`987ff5a0 00007ff9`9cce72ed     coreclr!Thread::UserSleep+0xbc
    05 00000027`987ff600 00007ff9`9c7ec46b     coreclr!ThreadNative::Sleep+0xad
    06 00000027`987ff750 00007ff9`3ddd6eac     System_Private_CoreLib!System.Threading.Thread.Sleep+0xb
    07 00000027`987ff780 00007ff9`9cd86c16     BuggyBits!BuggyBits.Models.Link.Finalize+0x1c
    08 00000027`987ff7c0 00007ff9`9cd28bf7     coreclr!FastCallFinalizeWorker+0x6
    09 00000027`987ff7f0 00007ff9`9cd28ad2     coreclr!MethodTable::CallFinalizer+0x97
    0a (Inline Function) --------`--------     coreclr!CallFinalizer+0x3d
    0b (Inline Function) --------`--------     coreclr!FinalizerThread::DoOneFinalization+0x3d
    0c 00000027`987ff830 00007ff9`9cd284f7     coreclr!FinalizerThread::FinalizeAllObjects+0xda
    0d 00000027`987ff920 00007ff9`9cd293c2     coreclr!FinalizerThread::FinalizerThreadWorker+0x97
    0e (Inline Function) --------`--------     coreclr!ManagedThreadBase_DispatchInner+0xd
    0f 00000027`987ff960 00007ff9`9cd292af     coreclr!ManagedThreadBase_DispatchMiddle+0x7e
    10 00000027`987ffa80 00007ff9`9cc85f3a     coreclr!ManagedThreadBase_DispatchOuter+0xaf
    11 (Inline Function) --------`--------     coreclr!ManagedThreadBase_NoADTransition+0x28
    12 (Inline Function) --------`--------     coreclr!ManagedThreadBase::FinalizerBase+0x28
    13 00000027`987ffb20 00007ff9`9cd734ca     coreclr!FinalizerThread::FinalizerThreadStart+0x7a
    14 00000027`987ffc40 00007ffa`9725257d     coreclr!Thread::intermediateThreadProc+0x8a
    15 00000027`987ffd00 00007ffa`9824af28     kernel32!BaseThreadInitThunk+0x1d
    16 00000027`987ffd30 00000000`00000000     ntdll!RtlUserThreadStart+0x28
    
  11. Compruebe el siguiente fragmento de código en el archivo Link.cs y verá que hay una llamada explícita a Thread.Sleep, lo que está causando un uso elevado de memoria.

    Nota:

    Como se mencionó anteriormente en el artículo, BuggyBits y el siguiente fragmento de código es específico de la aplicación de ejemplo que se usa para crear este ejemplo. Compruebe el código de la aplicación si encuentra un escenario similar y encontró un método específico en la aplicación que está causando un problema de memoria elevado en función del análisis de volcado de memoria.

    // BuggyBits.Models.Link 
    // Flags = reuse slot, hide by signature 
    protected override void Finalize() 
    { 
      try 
      { 
        System.Threading.Thread.Sleep(5000); 
      } 
      finally 
      { 
        base.Finalize(); 
      } 
      return; 
    } 
    

Más información