2015-02-13 6 views
5

Я отлаживал утечки ресурсов в своем приложении и создавал тестовое приложение для тестирования утечек объектов GDI. В OnPaint я создаю новые значки и новые растровые изображения без их удаления. После этого я проверяю увеличение объектов GDi в диспетчере задач для каждого из случаев. Однако, если я перекрашу основное окно моего приложения, количество объектов GDI увеличивается для значков, но изменений для растровых изображений нет. Есть ли какая-то особая причина, почему иконы не очищаются так же, как растровые изображения?Есть ли разница в использовании иконки и растровых изображений?

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

Результат теста:

  1. Нет иконки и растровые изображения - 30 GDI объектов
  2. с растровыми изображениями - 31 объект GDI, число не меняется.
  3. С помощью значков - 31, а затем число увеличивается, если вы перерисовываете окно.
+0

explcation Возможное, что это сборка мусора эффект: 'Bitmap' обычно * большой * в то время как' Icon' есть * маленький * настолько велик, 'Bitmap's вызвать вверх Мусорная коллекция, которая очищает «Bitmap's (и * dispose * them), но не' Icon ' –

+0

@DmitryBychenko. Должны ли новые созданные небольшие объекты принадлежать генерации 0 и чаще очищаться? – username

+0

да, поколение 0 склонно к сбору; Другая проблема заключается в том, что GC уделяет внимание размерам кэша процессора и т. д., поэтому большой объект может запускать сборку мусора. –

ответ

1

Я считаю, что вы должны заботиться о значках вручную. Я сделал несколько поисков и обнаружил, что GC заботится о растровых изображениях, но не о значках. Формы иногда содержат свою собственную копию значков (я не уверен, почему). Способ утилизации иконки можно найти здесь: 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); 
}