2015-09-15 34 views
19

Durante lo sviluppo dell'applicazione UWP ho trovato recentemente alcune perdite di memoria che impediscono la raccolta delle mie pagine da parte di GC. Ho un ContentPresenter sulla mia pagina come:Binding compilato UWP x: Bind produce perdite di memoria

<ContentControl Grid.Column="0" Grid.Row="1" Content="{x:Bind ViewModel.Schedule, Mode=OneWay}"> 
</ContentControl> 

Dopo che ho rimuovere il contenuto, o sostituirlo con dinamica {Binding} - pagina viene raccolto quando navigo da esso. Altrimenti rimane in memoria. È un bug o sto facendo qualcosa di sbagliato? C'è un modo per rilasciare e cancellare TUTTI i binding sulla navigazione?

UPDATE: sembra essere un problema noto all'interno di Microsoft come è stato affermato here. Ma per quanto posso vedere attraverso il mio utilizzo di test/app, i dati che vengono conservati da x: Bind vengono comunque raccolti dopo un po 'di tempo, quando, ad esempio, si naviga sulle stesse pagine o si creano gli stessi controlli per alcuni tempo. Ho potuto vedere che i nuovi oggetti sono stati creati, ma quelli vecchi a un certo punto sono stati raccolti.

Quindi per me non sembra essere un problema drastico che causa memoria insufficiente, ma non consente solo agli oggetti di essere raccolti così rapidamente come lo sarà il binding dinamico.

+0

@ O.O Grazie per la risposta! Dovrei solo correggere, che per la modalità predefinita dei binding compilati è OneTime, quindi devo specificare OneWay in questo caso. [collegamento] (https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx) alla documentazione – Viachslau

+0

@OO riguardante le perdite di memoria Ho visto il seguente comportamento in profiler: se ho dinamico binding: gli oggetti vengono raccolti su ogni istantanea dopo aver navigato dalla pagina. Con i binding compilati - non lo sono, MA in un momento i DO vengono raccolti, mentre alcuni di essi sono ancora conservati. – Viachslau

+0

Grazie per la correzione. Ho lo stesso problema nella mia app, ma con associazioni dinamiche e non sono stato in grado di isolare il problema a parte il fatto che la navigazione avanti e indietro esaspera il problema. Potresti provare a utilizzare l'evento OnNavigatedTo/From per cancellare il datacontext, i databindings e lo stack di navigazione. Se funziona nel tuo scenario, potresti anche abilitare il caching delle pagine. –

risposta

1

Sì, ha causa perdita di memoria, per evitare che è possibile utilizzare seguente procedura:

  1. Usa IoC come UnityContainer e rendere il vostro ViewModel o Visualizza ContainerControlLifeTime
  2. assegnare null alla proprietà ViewModel in xaml.cs una volta ti muovi dall'interfaccia utente.
3

Ho creato bug su Microsoft connect a causa di questo problema.

https://connect.microsoft.com/VisualStudio/feedback/details/3077894/memory-leaks-in-c-uwp-apps-using-compiled-x-bind-bindings

lavoro in giro per questo problema è quello di chiamare in modo esplicito Bindings.StopTracking() a pagina Unloaded gestore di eventi. È perché i binding compilati non usano il pattern "weak event" e si iscrivono direttamente all'evento PropertyChanged di INotifyPropertyChanged. È una causa di perdita di memoria. Per annullare l'iscrizione agli eventi, puoi chiamare Bindings.StopTracking(). Il codice dei binding compilato non lo chiama automaticamente.

+0

Per risolvere questo problema, è necessario chiamare esplicitamente Bindings.StopTracking() alla pagina Gestore di eventi scaricato. È perché i binding compilati non usano il pattern "weak event" e si iscrivono direttamente all'evento PropertyChanged di INotifyPropertyChanged. È una causa di perdita di memoria. Per annullare l'iscrizione agli eventi, puoi chiamare Bindings.StopTracking(). Il codice dei binding compilato non lo chiama automaticamente. –