¿Alguna idea sobre cómo escribir una regla de análisis estático (FXCop) para garantizar que se eliminen los delegados del evento?

StackOverflow https://stackoverflow.com/questions/854716

Pregunta

Hemos estado realizando un gran análisis de pérdida de memoria y hemos descubierto que uno de los factores contribuyentes ha sido la no eliminación de delegados en eventos que provocan que los objetos no se GC con la suficiente rapidez (o, a veces, para siempre).

¿Alguien tendría alguna idea sobre cómo escribir una regla en FXCop para garantizar que los delegados sean eliminados de los controladores?

Acabo de ver este y como tal pediré allí más información.

¿Fue útil?

Solución

Ok, además del problema de implementar la verificación real (en mi opinión, esto es muy similar a una cobertura de ruta y por lo tanto no es práctico): esta es la manera de escribir una nueva regla FxCop:

Al principio algunos artículos que me ayudaron una vez:

Implementar una regla simple no es gran cosa.En su proyecto necesita un archivo Rules.xml como recurso integrado (consulte aquí).Tu derivas tu clase de BaseIntrospectionRule y agregue su código al método Check():

public override ProblemCollection Check( TypeNode typeNode )
{
  if( type.IsPublic )
  {
    Problems.Add( new Problem( ... ) );
  }
  return Problems;
}

Hice esto hace algunas veces.Espero que todavía funcione como se describe :)

Otros consejos

Es necesario ser más específico. No es necesario para comprobar que todos los delegados de eventos no estaban suscritas, ya que en un caso común suscriptor vive la vida más corto que un editor. Y una pérdida de memoria sólo ocurre cuando el suscriptor parece ser más longevos que un editor, por lo tanto, hay una referencia, que impiden GC de recoger el objeto editor.

Ahora necesitamos comprobar que si se suscribe a un evento en un objeto relativamente de corta vida, se da de baja de la misma con el tiempo.

Una heurística que se me ocurre en este caso con: analizar todos los objetos locales variable (cuyo ámbito por el bloque de código actual {}) y todos los objetos, que se deshaga de forma explícita. Para cada evento en estos objetos contar el número de veces que se suscribe a ellos y el número de veces que se da de baja. Si el primer número es mayor que emitir una advertencia.

Por supuesto que no cubre todos los casos, pero supongo que hay un enfoque estático puede cubrir todos los casos de este problema, es necesario algún método que es lo suficientemente bueno.

no voy a hablar de las ventajas del análisis dinámico y de código comentarios aquí ya que es un tema aparte, no relacionada con la pregunta.

¿Se puede obligar a una regla que todas las suscripciones de eventos deben ser manejados a través WeakReferences? Estoy pensando que esto debería ser más fácil de implementar que tener que analizar la corriente real de su programa.

¿Es seguro asumir los objetos que implementan los manipuladores de alguna manera tienen referencias al objeto con los acontecimientos? Si ese es el caso que es mejor encontrar la manera de romper el ciclo de otra manera.

Hemos tenido algo similar pasando un tiempo con controladores de eventos en las páginas ASP.NET. Los objetos que implementan los manipuladores también tenían referencias a las páginas. Después de romper ya que muchos de los enlaces arquitectónicamente como pudimos, los pocos restos de comida se cambiaron a WeakReferences. No hay más problemas de memoria!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top