Memory leakage usually means that after an application completes its life cycle, some objects are accidentally referenced by other objects, resulting in subsequent GC failure to recycle them. In the long run, it will lead to program performance degradation and potential OutOfMemoryException.
In this article, we use a memory leak tool Net core program for memory leak analysis. If the program is running on windows, you can directly use visual studio for diagnosis.
Check managed memory usage
Before analyzing the memory leak, you must have evidence to prove that there is a memory leak. Here, you can use dotnet counters to check the various indicators of the application.
Run the program
Find the PID of the program,
dotnet-counters ps 4807 DiagnosticScena /home/user/git/samples/core/diagnostics/DiagnosticScenarios/bin/Debug/netcoreapp3.0/DiagnosticScenarios
Use monitor to start the monitor. Here –refresh interval means refresh interval
dotnet-counters monitor --refresh-interval 1 -p 4807 Press p to pause, r to resume, q to quit. Status: Running [System.Runtime] # of Assemblies Loaded 118 % Time in GC (since last GC) 0 Allocation Rate (Bytes / sec) 37,896 CPU Usage (%) 0 Exceptions / sec 0 GC Heap Size (MB) 4 Gen 0 GC / sec 0 Gen 0 Size (B) 0 Gen 1 GC / sec 0 Gen 1 Size (B) 0 Gen 2 GC / sec 0 Gen 2 Size (B) 0 LOH Size (B) 0 Monitor Lock Contention Count / sec 0 Number of Active Timers 1 ThreadPool Completed Work Items / sec 10 ThreadPool Queue Length 0 ThreadPool Threads Count 1 Working Set (MB) 83
Focus on the GC heap size (MB) indicator. You can see that the current GC heap memory is 4m after the program is started. Open the link: https://localhost:5001/api/diagscenario/memleak/20000 Then look at the GC heap memory. You can see that it is 30m at once, as shown below:
GC Heap Size (MB) 30
By comparing the use of memory, it can be said to confirm the memory leak.
Generate dump file
To analyze the memory leak of a program, you must first have access to the GC heap, so that you can analyze the heap memory and the relationship between objects, and then you can boldly guess why the memory has not been released? To generate Net core program dump file, with the help of dotnet dump tool.
dotnet-dump collect -p 4807 Writing minidump with heap to ./core_20190430_185145 Complete
Analyze core dump
Next, you can use dotnet dump analyze to analyze the generated dump file.
dotnet-dump analyze core_20190430_185145
Core here_ 20190430_ 185145 is the dump name you want to analyze. It is worth mentioning that if you encounter libdl So cannot be found error. It is recommended to install the libc6 dev package.
First, we use the SOS command to view the statistical list of all objects on the managed heap.
> dumpheap -stat Statistics: MT Count TotalSize Class Name ... 00007f6c1eeefba8 576 59904 System.Reflection.RuntimeMethodInfo 00007f6c1dc021c8 1749 95696 System.SByte 00000000008c9db0 3847 116080 Free 00007f6c1e784a18 175 128640 System.Char 00007f6c1dbf5510 217 133504 System.Object 00007f6c1dc014c0 467 416464 System.Byte 00007f6c21625038 6 4063376 testwebapi.Controllers.Customer 00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer 00007f6c1dc00f90 206770 19494060 System.String Total 428516 objects
From the output, most of them are string and customer objects. Then you can get all the instance objects under the method table through the MT parameter.
> dumpheap -mt 00007faddaa50f90 Address MT Size ... 00007f6ad09421f8 00007faddaa50f90 94 ... 00007f6ad0965b20 00007f6c1dc00f90 80 00007f6ad0965c10 00007f6c1dc00f90 80 00007f6ad0965d00 00007f6c1dc00f90 80 00007f6ad0965df0 00007f6c1dc00f90 80 00007f6ad0965ee0 00007f6c1dc00f90 80 Statistics: MT Count TotalSize Class Name 00007f6c1dc00f90 206770 19494060 System.String Total 206770 objects
You can use it next! Gcroot checks who owns a string?
> gcroot -all 00007f6ad09421f8 Thread 3f68: 00007F6795BB58A0 00007F6C1D7D0745 System.Diagnostics.Tracing.CounterGroup.PollForValues() [/_/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs @ 260] rbx: (interior) -> 00007F6BDFFFF038 System.Object -> 00007F69D0033570 testwebapi.Controllers.Processor -> 00007F69D0033588 testwebapi.Controllers.CustomerCache -> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer, DiagnosticScenarios]] -> 00007F6C000148A0 testwebapi.Controllers.Customer -> 00007F6AD0942258 testwebapi.Controllers.Customer -> 00007F6AD09421F8 System.String HandleTable: 00007F6C98BB15F8 (pinned handle) -> 00007F6BDFFFF038 System.Object -> 00007F69D0033570 testwebapi.Controllers.Processor -> 00007F69D0033588 testwebapi.Controllers.CustomerCache -> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer, DiagnosticScenarios]] -> 00007F6C000148A0 testwebapi.Controllers.Customer -> 00007F6AD0942258 testwebapi.Controllers.Customer -> 00007F6AD09421F8 System.String Found 2 roots.
From the reference chain of string, it is held by customercache, and then you can find problems in the code.
Original link: https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-memory-leak
This is about how to check Net memory leak, more related troubleshooting Net memory leak content, please search the previous articles of developeppaer or continue to browse the related articles below. I hope you can support developeppaer in the future!