2015-02-13 93 views
5

Stavo eseguendo il debug delle perdite di risorse nella mia applicazione e ho creato un'app di test per verificare le perdite di oggetti GDI. In OnPaint creo nuove icone e nuove bitmap senza eliminarle. Successivamente, controllo l'aumento degli oggetti GDi nel task manager per ciascuno dei casi. Tuttavia, se continuo a ridipingere la finestra principale della mia app, il numero di oggetti GDI aumenta per le icone, ma non c'è alcun cambiamento per le bitmap. C'è qualche ragione particolare per cui le icone non vengono ripulite allo stesso modo delle bitmap?Esiste una differenza nello smaltimento di icone e bitmap?

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     // 1. icon increases number of GDI objects used by this app during repaint. 
     //var icon = Resources.TestIcon; 
     //e.Graphics.DrawIcon(icon, 0, 0); 

     // 2. bitmap doesn't seem to have any impact (only 1 GDI object) 
     //var image = Resources.TestImage; 
     //e.Graphics.DrawImage(image, 0, 0); 
    } 
} 

Risultato del test:

  1. Nessuna icona e bitmap - 30 oggetti GDI
  2. con le bitmap - 31 GDI oggetto, il numero non cambia.
  3. Con icone - 31 e quindi il numero aumenta se si ridisegna la finestra.
+0

explcation Posible è che il suo effetto garbage collection: 'Bitmap' è di solito * grande *, mentre' Icon' è * * piccola così grande 'Bitmap's attivare fino Garbage Collection che cancella 'Bitmap's (e * li elimina *) ma non' Icon's –

+0

@DmitryBychenko I piccoli oggetti appena creati non appartengono alla generazione 0 e vengono puliti più frequentemente? – username

+0

sì, la generazione 0 è incline alla raccolta; un altro problema è che GC presta attenzione alle dimensioni della cache della CPU, ecc. quindi un oggetto di grandi dimensioni può attivare la garbage collection. –

risposta

1

Credo che sia necessario occuparsi delle icone manualmente. Ho fatto alcune ricerche e ho scoperto che GC si occupa delle bitmap ma non delle icone. Le forme a volte conservano la propria copia delle icone (non sono sicuro del perché). Un modo per smaltire le icone può essere trovato qui: http://dotnetfacts.blogspot.com/2008/03/things-you-must-dispose.html

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
extern static bool DestroyIcon(IntPtr handle); 

private void GetHicon_Example(PaintEventArgs e) 
{ 
// Create a Bitmap object from an image file. 
Bitmap myBitmap = new Bitmap(@"c:\FakePhoto.jpg"); 

// Draw myBitmap to the screen. 
e.Graphics.DrawImage(myBitmap, 0, 0); 

// Get an Hicon for myBitmap. 
IntPtr Hicon = myBitmap.GetHicon(); 

// Create a new icon from the handle. 
Icon newIcon = Icon.FromHandle(Hicon); 

// Set the form Icon attribute to the new icon. 
this.Icon = newIcon; 

// Destroy the Icon, since the form creates 
// its own copy of the icon. 
DestroyIcon(newIcon.Handle); 
}