Spesso anch’io mi rendo colpevole di questa ‘worst practice’.
Beh, sono umano.
Ammetto di aver cominciato ad usare i weak references solo da poche settimane, e mi dispiace di non aver cominciato prima.
Cosa sono i weak references ? Sono uno strumento utile a migliorare la gestione della memoria presente in molti dei linguaggi moderni che supportano un meccanismo di garbage collector, al quale i weak references sono strettamente legati.
Il classico meccanismo del garbage collector prevede che un oggetto rimanga allocato in memoria finchè è puntato da almeno un reference. Quando l’ultimo dei reference rilascia l’oggetto, questo diventa ‘garbage’, spazzatura, e viene liberato dalla memoria non appena viene eseguito il meccanismo di garbage collection.
I reference a cui ho accennato si possono definire, in questo ambito, strong reference. Il weak reference, per contrasto, è un puntatore ad un oggetto che non impedisce a quell’oggetto di finire nel garbage collector.
(uh !!)
E’ come giocare col fuoco, no ? Un puntatore ad un oggetto che può scomparire dalla memoria in qualunque momento ?
Ma quale idiota può aver inventato uno strumento così folle ?
Lo scenario tipico
Supponiamo, tanto per fare un esempio, di avere una applicazione con una ricca interfaccia grafica divisa in tante pagine. L’applicazione propone una ed una sola pagina per volta, e l’utente può navigare tra le pagine a piacimento.Le pagine, a causa di un opulente uso di risorse grafiche (sprite, sfondi, suoni ed altre amenità simili), sono molto pesanti, e a causa del consumo importante di memoria vengono caricate lentamente.
Il programmatore, per sviluppare questo tipo di applicazione, può optare per tre strade:
1. Allocare più pagine possibili in memoria per rendere veloce il passaggio da una pagina e l’altra. Massimizzando le prestazioni, l’applicazione richiederà tuttavia risorse molto importanti e i requisiti di sistema potrebbero diventare proibitivi su certi hardware.
2. Allocare il minor numero di pagine possibili in memoria (idealmente solo quella attiva), e accettare la lentezza nel passaggio tra una pagina e un’altra. L’applicazione consumerà poca memoria, ma la lentezza dell’interfaccia potrebbe togliere parecchi punti alla ‘user experience’.
3. Progettare un meccanismo di cache intelligente in modo da allocare un ‘buon’ numero di pagine in memoria scegliendo tra quelle più utilizzate oppure tra i percorsi di navigazione più probabili.
La scelta 3 è evidentemente la migliore, per quanto riguarda i risultati.
Però è anche costosa.
Se non è già sa disposizione una simile cache, occorre progettare un meccanismo di allocazione e rilascio delle pagine che, quanto a performance tuning e messa a punto degli algoritmi, può risultare molto impegnativo e richiedere parecchie ore-uomo.
Esiste, per fortuna, una quarta opzione:
4. Usare dei weak references alle pagine.
E’ possibile allocare le pagine e, nel momento in cui vengono rilasciate, ‘agganciarle’ ad un weak reference. A questo punto le pagine sono potenzialmente disallocabili ma, se l’utente richiama nuovamente una pagina prima che questa venga liberata dalla memoria, allora è possibile ‘resuscitarla’ dalla morte in modo molto veloce, senza dover riallocare nulla.
Per comprendere quanto il codice sia semplice, ecco un esempio:
WeakReference wr = new WeakReference(bigFatPage); bigFatPage = null;
Questo codice mostra la fase di disallocazione di una grossa pagina con relativa attivazione del weak reference. Notare che mettendo il reference della pagina a null (sempre che quello sia l’ultimo reference presente) la stiamo di fatto condannando alla disallocazione, ma …
bigFatPage = wt.Target as FatPageClass;
if (bigFatPage == null)
{
bigFatPage = new FatPageClass(context);
}.. nel momento in cui abbiamo di nuovo bisogno della pagina, ecco che tramite la proprietà Target del weak reference possiamo far tornare in vita la pagina. Fatto !
Semplice, anche se occorre notare che il weak reference potrebbe tornare un valore nullo se la pagina è stata disallocata. In questo caso, pazienza, la pagina va ricreata di nuovo.
In conclusione, i weak references rappresentano un modo poco sofisticato (i risultati non sono assicurati) ma semplice e veloce per ottimizzare l’uso di oggetti molto pesanti.
Se avete fiducia nel garbage collector e avete problemi di prestazioni, vale la pena provarlo.
Se poi non funziona, a voi progettare la sofisticatissima cache …
0 commenti:
Posta un commento
Perchè non lasciare un commento intelligente ? Si accetta di tutto a parte lo spam e le volgarità ..