写此文目的在于备份,以供日后查阅。
GDI泄露这玩意儿以前压根没听过, 第一次了解到这东西存在是在很久很久以前在我们的项目中真实遇到过了,当时的情况是这样的一同事发现狂点菜单某一选项几分钟,程序就会crash,而且每次都能重现,起初猜测是资源泄露,后来打开任务管理器监视GDI Object一栏发现每点一次菜单,GDI Object的数量就飙涨,差不多到10000的时候程序就会crash。当时很佩服那同事咋能发现那Bug,也惊奇任务管理器竟然能监视那么多的资源利用。
最后发现栽在于创建Bitmap却忘记释放,好像跟Handler有关(嗯,忘了O(∩_∩)O哈哈~)
最近发现如下代码,直觉告诉我这里也应该有GDI泄露问题。
Create Icon From Bitmap
1public static System.Drawing.Icon FromBitmapToIcon(System.Drawing.Bitmap bitmap)
2{
3 if (null == bitmap)
4 return null;
5 IntPtr handler = bitmap.GetHicon();
6 if (null != handler)
7 {
8 System.Drawing.Icon result = System.Drawing.Icon.FromHandle(handler);
9 return result;
10 }
11 return null;
12}
13
写个测试程序,发现每调用一次FromBitmapToIcon()方法,GDI Object的数量就+3,如果点击如下测试程序中的Button超过10次,程序就会crash(GDI Object的数量 达到了9999上线)。
Test Code
1private void button1_Click(object sender, EventArgs e)
2{
3 for (int i = 0; i < 333; i++)
4 {
5 Icon icon = FromBitmapToIcon(Properties.Resources.Background);
6 icon.Dispose();
7 }
8}
9
捕捉到的异常如下:
解决的方法是,创建了Icon对象后调用