c# - studio - Obtener referencias activas a un objeto
referencia a un objeto no establecida (3)
Estoy buscando una API administrada / no administrada que me permita encontrar qué objetos hacen referencia a otro objeto y potencialmente evitar que se recopile basura.
Tal API podría verse así:
var foo = new Foo();
var bar = new Bar();
bar.Foo = foo;
var references = GC.GetReferencesTo(foo);
// references is an array that contains bar
Sé que los perfiladores se pueden usar para esto, pero me gustaría hacer que forme parte de una prueba unitaria. ¿Hay una API administrada o no administrada que pueda usar?
.NET Profiler usa la API de creación de perfiles para rastrear el gráfico de objetos. Es posible que esté particularmente interesado en los métodos de devolución de llamada ObjectReferences
y RootReferences
, y quizás también en ObjectAllocated
. Los primeros dos métodos serán llamados para cubrir todo el gráfico del objeto vivo después de cada recolección de basura, por lo que interceptarlos solos es suficiente para reconstruir ese gráfico, y luego analizarlo de la manera que desee.
Este artículo explica cómo juntar todas las piezas.
El dll no administrado SOS (Son Of Strike) proporciona un medio para lograr esto, aunque no creo que tenga un soporte de scripting significativo, ni proporciona un medio simple para lograr esto a través de un solo comando. Tendría que introspectar la dirección de la variable, verificar todos los macros de la variable (que incluiría obviamente la pila) y tratar con el resto.
Sugeriría que, si desea probar que un objeto no está referenciado, una técnica más simple sería (temporalmente) hacerlo finalizable, asegúrese de que ya no se haga referencia en la pila de su prueba de unidad y luego fuerce varias recolecciones de basura a través de GC.Collect () luego usa GC.WaitForPendingFinalizers () .
Su método de finalización puede establecer una bandera booleana estática y luego su prueba unitaria puede afirmar que esto es cierto.
Me gustaría cuestionar la utilidad de esto sin más explicaciones, pero este es probablemente el método más simple para probar que no existen referencias pendientes en una prueba unitaria.
Recuerde también .NET utiliza la recolección de elementos no utilizados rastreada para que los objetos referenciados por otros objetos, por ejemplo, un gráfico de objetos, sigan siendo limpiados por el GC si su aplicación ya no hace referencia a ninguno de ellos; es mucho más inteligente que los clásicos algoritmos de conteo de basura de conteo pre.NET. Esto significa que incluso cuando encuentre una manera de identificar todas las referencias a un objeto, algunas de ellas pueden no ser importantes y es posible que no necesiten ser atendidas.
Esto no responde directamente a cómo encontrar todas las referencias a un objeto, pero sí hace que los lectores se den cuenta de la situación en la que, cuando encuentras todas las referencias a través de una herramienta o utilidad, no es necesario reparar algunos tipos de cosas. más tiempo en .NET, por ejemplo, referencias circulares clásicas y, por lo tanto, es posible que tenga que buscar algunas formas ingeniosas de saber qué ignorar cuando se trata de reparar fugas de memoria.
Esta explicación solo se aplica al escenario de código administrado.