2015-02-13 22 views
5

Uygulamamda kaynak sızıntılarını hata ayıklıyordum ve GDI nesne sızıntılarını test etmek için bir test uygulaması oluşturdum. OnPaint'te onları yok etmeden yeni simgeler ve yeni bitmapler oluşturuyorum. Bundan sonra, her durum için görev yöneticisinde GDi nesnelerini kontrol ediyorum. Ancak, uygulamamın ana penceresini yeniden boyamaya devam edersem, simgeler için GDI nesnelerinin sayısı artar, ancak bitmap'ler için herhangi bir değişiklik yoktur. Simgelerin bitmapler ile aynı şekilde temizlenmemesinin özel bir nedeni var mı?Simge ve Bitmap atmada bir fark var mı?

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); 
    } 
} 

Test Sonucu:

  1. Simge yok ve nbspbitmap'lerdir - 30 GDI bitmapler ile
  2. nesneleri - 31 GDI nesnesi, sayı değişmez.
  3. Simgelerle - 31 ve sonra pencereyi yeniden boyarsanız sayı artar.
+0

Posible explcation çöp toplama etkisi olmasıdır: 'bitmap genellikle' Icon' iken * büyük * * küçük * çok büyük 'Bitmap's kadar tetikleyebilir Çöp Toplama 'Bitmap' s (ve * onları * atmayın) temizler ama değil 'Simge' –

+0

@DmitryBychenko Yeni oluşturulan küçük nesneler 0 nesline ait olmalı ve daha sık temizlenmelidir? – username

+0

evet, nesil 0 toplanmaya eğilimli; Başka bir sorun ise GC'nin CPU önbellek boyutlarına vb. önem vermesidir, böylece büyük bir nesne çöp toplama işlemini tetikleyebilir. –

cevap

1

Simgelere elle bakmanız gerektiğine inanıyorum. Bazı araştırmalar yaptım ve GC'nin bitmap'leri önemsediğini, ancak simgeleri görmediğini keşfettim. Formlar bazen simgelerin kendi kopyasını saklıyor (emin değilim). simgeleri elden bir yolu burada bulabilirsiniz: 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); 
} 
İlgili konular