Tutte le idee su come scrivere una regola di analisi statica (FxCop) per assicurare che i delegati degli eventi vengono rimossi

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

Domanda

Ci sono state andando attraverso un grande analisi perdita di memoria e hanno trovato uno dei fattori che contribuiscono è stata la non rimozione di delegati sugli eventi causando oggetti per non essere GCed abbastanza in fretta (o, a volte per sempre).

Qualcuno ha qualche idea su come scrivere una regola FxCop per garantire che abbiamo i delegati vengono rimossi da gestori?

e come tale io' ll chiedere lì per ulteriori informazioni.

È stato utile?

Soluzione

Ok, accanto al problema di attuare il controllo effettivo (a mio parere questo è molto simile a un copertura e quindi non pratico) - qui è il modo di scrivere una nuova FxCop regola è:

:

Al primo qualche articolo che mi ha aiutato una volta:

L'implementazione di un semplice regola è un grosso problema. Nel progetto è necessario un file rules.xml come risorsa incorporata (vedi qui ). Si deriva la classe da BaseIntrospectionRule e aggiungere il codice per il Check () - Metodo:

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

L'ho fatto qualche tempo fa. Spero che funziona ancora come descritto:)

Altri suggerimenti

Hai bisogno di essere più specifico. Non è necessario controllare che tutti i delegati di evento erano sottoscritte, perché in un caso comune un abbonato vive di vita più breve di un editore. E una perdita di memoria avviene solo quando il vostro abbonato sembra essere più longevo di un editore, e quindi v'è un riferimento, che impediscono GC di raccogliere l'oggetto editore.

Ora dobbiamo verificare che se si sottoscrive un evento su un oggetto relativamente breve che vivono, si annulla la sottoscrizione da esso alla fine.

Un'euristica posso venire con, in questo caso: analizzare tutti gli oggetti locali variabile (che hanno come ambito dal blocco di codice corrente {}) e tutti gli oggetti, che si smaltisce in modo esplicito. Per ogni evento su questi oggetti contare il numero di volte in cui si è abbonati a loro e il numero di volte che si annullare l'iscrizione. Se il primo numero è maggiore di emettere un avvertimento.

Certo che non copre tutti i casi, ma credo che nessun approccio statico in grado di coprire tutti i casi in questo problema, è necessario un metodo che è abbastanza buono.

non voglio parlare dei vantaggi di analisi dinamica e il codice recensioni qui in quanto è un argomento a parte, non è legato alla domanda.

Si può forzare una regola che tutte le sottoscrizioni di eventi devono essere gestite attraverso WeakReferences? Sto pensando che questo dovrebbe essere più facile da implementare che dover analizzare la portata effettiva del programma.

E 'sicuro di assumere gli oggetti che implementano i gestori in qualche modo avere riferimenti di nuovo l'oggetto con gli eventi? Se questo è il caso è meglio capire come rompere il ciclo in un altro modo.

Abbiamo avuto qualcosa di simile sta succedendo un po 'indietro con i gestori di eventi sulle pagine ASP.NET. Gli oggetti che hanno implementato i gestori avevano anche riferimenti a pagine. Dopo la rottura, come molti dei collegamenti architectually come abbiamo potuto, i pochi avanzi sono stati modificati per WeakReferences. Non più problemi di memoria!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top