Domanda

Sfondo dell'applicazione

La nostra piattaforma è un'applicazione WPF click-once. Abbiamo una "shell" che contiene una struttura di menu di navigazione e ospita la nostra pagina " classi. Quando navighi in una nuova pagina, scambiamo il contenuto della shell (essenzialmente).

Problema

Quindi lavoro per un'azienda che sta lavorando a un progetto software estremamente ampio. Abbiamo molto codice con cui abbiamo riscontrato problemi di memoria.

Il problema è che ci sono molti posti nella nostra applicazione in cui gli eventi sono cablati e mai indesiderati. Non sono sicuro del motivo per cui gli sviluppatori lo stessero facendo, immagino che si aspettassero che gli oggetti venissero ripuliti ogni volta che un utente naviga in una nuova "pagina".

Non abbiamo la possibilità di refactoring di ogni pagina (in questa versione). Esiste un modo con C # per rimuovere tutti i riferimenti da un oggetto? (Consentendo quindi al garbage collector di gettare via quell'oggetto, insieme a tutti i suoi riferimenti interni)

Stiamo cercando di recuperare questa memoria, ma è abbastanza complicato trovare oggetti che fanno ancora riferimento alle nostre pagine (riferimenti a oggetti), quando abbiamo WPF da gestire.

Abbiamo esaminato gli alberi visivi e logici e utilizzato applicazioni di profilazione per aiutarci a ripulire manualmente le cose (per provare l'idea) e anche questo si è rivelato estremamente difficile.

Mi sono seduto e ho pensato, perché stiamo facendo tutto questo lavoro per trovare riferimenti a oggetti, non possiamo semplicemente "dereference"? questa "pagina" quando è chiuso?

Il che mi porta qui :)
Qualsiasi aiuto è molto apprezzato!


AGGIORNAMENTO 1

Nei commenti è stato chiesto quanto segue:

Q: L'app funziona. hai davvero problemi di memoria? Come vengono esposti / rilevati? O questa memoria è in giro fino a quando non si verifica un GC2? & # 8211; Mitch Wheat

A: ha problemi di memoria. Se lasciamo una pagina (la proprietà che contiene la pagina viene impostata su un nuovo oggetto) il vecchio oggetto non viene mai raccolto dal Garbage Collector. Quindi la memoria continua a crescere. Se la nostra azienda ha ricominciato, con questa applicazione. La prima cosa che dovremmo considerare sarebbe l'implementazione di WeakEvent Patterns e l'utilizzo di più comandi indirizzati in WPF.

AGGIORNAMENTO 2

Sono stato in grado di trovare il mio soluzione .

È stato utile?

Soluzione 2

Ho implementato WeakEvents per risolvere questo problema.

Sfortunatamente, Microsoft consiglia di utilizzare WeakEventManager come classe di base e creare un tipo di gestore per OGNI evento nell'applicazione !!! Ho provato a scrivere un manager che eredita da questa base e farlo diventare più "generico" (non nel termine C # per generico). Questo "comune" Il gestore eventi non era possibile con la classe base di Microsoft. Ho dovuto scrivere un gestore di eventi da zero.

Grazie per l'aiuto inviato a questa domanda.

Altri suggerimenti

Hai usato il CLRProfiler? Lo trovo abbastanza bravo nel trovare oggetti e anche trovare ciò che contiene un riferimento ad essi.

Questo " come fare " pagina ...

http://msdn.microsoft.com/en-us/library /ms979205.aspx

... collega al sito di download.

Tuttavia, penso che la risposta alla tua domanda sia "no". Non esiste un modo per dire che l'oggetto non è più necessario: raccoglilo per favore indipendentemente dal fatto che sia radicato o meno. La raccolta di un oggetto rooted potrebbe introdurre ogni sorta di cattiveria nella tua app.

Se una pagina vuota non rientra nell'ambito, inclusi tutti i dati sottostanti, il GC la raccoglierà. Infine. Tuttavia, se a quella pagina viene fatto riferimento da qualcosa che è ancora nell'ambito, la pagina e tutti i suoi dati rimarranno in memoria e il GC non sarà in grado di raccoglierla.

Per quanto ne so non esiste un pulsante facile quando si tratta di correggere una cattiva gestione della memoria. Questo significa che l'unico, secondo me, è fare il lavoro per ripulire i riferimenti. Ciò renderà più semplice per il GC la raccolta di oggetti che non rientrano nell'ambito di applicazione.

Puoi suggerire al GC di esaminare il suo algoritmo per vedere se qualcosa può essere raccolto chiamando GC.Collect (). Tuttavia, questo farà ben poco oltre a sprecare i cicli della CPU a meno che i dati non siano veramente fuori portata.

Domanda per Phobis, quanta memoria utilizza l'applicazione?

EDIT:

Collegamento a CLR Profiler 2.0 che dovrebbe funzionare con le app .net3.5. http://www.microsoft. com / downloads / Details.aspx FamilyID = a362781c-3870-43be-8926-862b40aa0cd0 & amp;? displaylang = it

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