Tengo una aplicación que tiene algunas pérdidas de memoria debido a eventos que no se separan antes de que una referencia de objeto se establezca en nulo. La aplicación es bastante grande y es difícil encontrar las pérdidas de memoria al mirar el código. Quiero usar sos.dll para encontrar los nombres de los métodos que son la fuente de las filtraciones, pero me estoy atascado. Configuré un proyecto de prueba para demostrar el problema.C# Fugas de memoria basadas en eventos
Aquí tengo 2 clases, una con un evento, y sobre las escuchas a ese evento de la siguiente manera
namespace MemoryLeak
{
class Program
{
static void Main(string[] args)
{
TestMemoryLeak testMemoryLeak = new TestMemoryLeak();
while (!Console.ReadKey().Key.Equals('q'))
{
}
}
}
class TestMemoryLeak
{
public event EventHandler AnEvent;
internal TestMemoryLeak()
{
AnEventListener leak = new AnEventListener();
this.AnEvent += (s, e) => leak.OnLeak();
AnEvent(this, EventArgs.Empty);
}
}
class AnEventListener
{
public void OnLeak()
{
Console.WriteLine("Leak Event");
}
}
}
rompo en el código, y en el tipo de ventana intermedia
.load sos.dll
luego utilizo! dumpheap para obtener los objetos en el montón de la AnEventListener tipo
!dumpheap -type MemoryLeak.AnEventListener
y consigo el fo llowing
PDB symbol for mscorwks.dll not loaded
Address MT Size
01e19254 0040348c 12
total 1 objects
Statistics:
MT Count TotalSize Class Name
0040348c 1 12 MemoryLeak.AnEventListener
Total 1 objects
yo uso! gcroot de averiguar por qué el objeto no está siendo recolectado
!gcroot 01e19254
y obtener la siguiente
!gcroot 01e19254
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Error during command: Warning. Extension is using a callback which Visual Studio
does not implement.
Scan Thread 5208 OSTHread 1458
ESP:2ef3cc:Root:01e19230(MemoryLeak.TestMemoryLeak)->
01e19260(System.EventHandler)->
01e19248(MemoryLeak.TestMemoryLeak+<>c__DisplayClass1)->
01e19254(MemoryLeak.AnEventListener)
Scan Thread 7376 OSTHread 1cd0
Ahora puede ver el controlador de eventos que se la fuente de la fuga Yo uso! Hacer para mirar a los campos del controlador de eventos y obtener
!do 01e19260
Name: System.EventHandler
MethodTable: 65129dc0
EEClass: 64ec39d0
Size: 32(0x20) bytes
(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
65130770 40000ff 4 System.Object 0 instance 01e19248 _target
6512ffc8 4000100 8 ...ection.MethodBase 0 instance 00000000 _methodBase
6513341c 4000101 c System.IntPtr 1 instance 0040C060 _methodPtr
6513341c 4000102 10 System.IntPtr 1 instance 00000000 _methodPtrAux
65130770 400010c 14 System.Object 0 instance 00000000 _invocationList
6513341c 400010d 18 System.IntPtr 1 instance 00000000 _invocationCount
Así que ahora puedo ver el puntero al método que no está siendo separada
0040C060 _methodPtr
pero ¿Cómo llego el nombre de ese método?
Por favor, consulte mi respuesta a esta pregunta para saber cómo obtener _methodPtr http://stackoverflow.com/questions/3668642/get-method-name-form-delegate-with-windbg/3682594 # 3682594 –
Guau, esto es bastante bonito explicación aproximada de un examen de depuración. Upvote por tomarse el tiempo de publicar un ejemplo detallado, y puede que otros lo usen en el futuro. Voy a marcar esto. –