in

UgiMobile.org

Il primo User Group Italiano dedicato a Windows Mobile

Mirco Vanini

Embedded life tips

GDI – Leak – WinCE – C#

Suona strano avere dei memory leak in codice gestito ma sono molto più frequenti di quello che si possa pensare. Alcune settimane fà ho tenuto una sessione di code review presso un mio cliente e ho speso alcuni giorni a sistemare diversi memory leak su una programma scritto in C# per Windows CE.

Quello che bisogna tenere a mente che tutti gli oggetti GDI (Bitmap, Font, Brush, Pen, ecc.) di C# in realtà sono dei wrapper sopra oggetti Win32. Tali oggetti sono referenziati tramite Handle e devono essere rilasciati. Il GC non lo fà per voi in modo automatico perchè semplicemente non li può gestire. Sopratutto nelle applicazioni mobile, in cui le risorse sono limitate, bisogna porre particolare attenzione a questo.

Durante la sessione di debug ho utilizzato questo tool (GDIView) che mi ha aiutato a verificare quali handle non venivano rilasciati.

Alcuni consigli pratici:

  • Richiamare sempre il Dispose di tutti gli oggetti grafici utilizzati, meglio ancora usare sempre la keword “using” per richiamare sempre in modo implicito il Dispose, esempio:
   1: SolidBrush fillBrush = new SolidBrush(Color.White);
   2: graphImage.FillRectangle(fillBrush, 0, 0, UI_CLIENT_WIDTH, UI_HEIGHT);
   3: fillBrush.Dispose();
   4:  
   5: // or
   6:  
   7: using(SolidBrush fillBrush = new SolidBrush(Color.White))
   8: {
   9:     graphImage.FillRectangle(fillBrush, 0, 0, UI_CLIENT_WIDTH, UI_HEIGHT);
  10: }
  11:  

 

  • Quando si riassegna una Bitmap assicurarsi che l’oggetto precedente sia deallocato, esempio:
   1: // wrong
   2: picCapture.Image = new Bitmap(32, 32);
   3:  
   4: // good
   5: if(picCapture.Image != null)
   6:     picCapture.Image.Dispose();
   7: picCapture.Image = new Bitmap(32, 32);

 

  • Quando si utilizza una Image contenuta in una ImageList è bene ricordare quanto esposto su MSDN: “The returned bitmap is a copy of the original image and should be disposed of using the Image.Dispose method.”. In altre parole tutte le get da una ImageList clonano una nuova immagine che deve essere rilasciata tramite un Dispose!
  • Quando si utilizzano direttamente le funzioni native Win32 porre attenzione se queste ritornano una nuova istanza di una risorsa in memoria. Leggere attentamente la loro documentazione!
  • Ogni volta che si alloca memoria tramite funzioni native Win32 è vostra responsabilità deallocarla.
  • Quando si crea un nuovo oggetto non gestito, salvare il riferimento (handle) in una variabile non accessibile dall’esterno. Se per qualsiasi motivo il riferimento viene sovrascritto non sarà più possibile deallocare correttamente la risorsa non gestita.
Only published comments... Mar 04 2009, 09:08 AM by Mirco Vanini
Filed under: ,

About Mirco Vanini

 Mirco Vanini è un consulente focalizzato sullo sviluppo di soluzioni mobile utilizzando sia .NET Compact Framework che SDK nativi. A partire dagli anni 90 ha sviluppato applicazioni utilizzando le varie tecnologie presenti sul mercato. Dal 2001 ha incominciato a sviluppare con Microsoft .NET sia per l'ambiente desktop che per l'ambiente mobile. Da sempre affronta lo sviluppo mobile utilizzando sia codice managed che codice nativo per ottenere sempre il massimo delle performance dai vari dispositivi. Alla base della sua filosofia vi è la semplicità e un constante aggiornamento professionale, credendo che la tecnologia non sia un ostacolo al cambiamento ma costituisca un valore aggiunto da comprendere e da sfruttare.

Powered by Community Server (Commercial Edition), by Telligent Systems