Icon.FromHandle(handler) 小心GDI泄露导致Crash

来源:Anders06  CNBlogs

写此文目的在于备份,以供日后查阅。

GDI泄露这玩意儿以前压根没听过, 第一次了解到这东西存在是在很久很久以前在我们的项目中真实遇到过了,当时的情况是这样的一同事发现狂点菜单某一选项几分钟,程序就会crash,而且每次都能重现,起初猜测是资源泄露,后来打开任务管理器监视GDI Object一栏发现每点一次菜单,GDI Object的数量就飙涨,差不多到10000的时候程序就会crash。当时很佩服那同事咋能发现那Bug,也惊奇任务管理器竟然能监视那么多的资源利用。

最后发现栽在于创建Bitmap却忘记释放,好像跟Handler有关(嗯,忘了O(∩_∩)O哈哈~)

最近发现如下代码,直觉告诉我这里也应该有GDI泄露问题。

Create Icon From Bitmap

写个测试程序,发现每调用一次FromBitmapToIcon()方法,GDI Object的数量就+3,如果点击如下测试程序中的Button超过10次,程序就会crash(GDI Object的数量 达到了9999上线)。

Test Code

GDILeak

捕捉到的异常如下:

image 

解决的方法是,创建了Icon对象后调用如下方法释放Handler:

[DllImport("user32.dll")]

public static extern bool DestroyIcon(IntPtr handle);

还有个用来释放对象的方法为:

[DllImport("gdi32.dll")]

public static extern bool DeleteObject(IntPtr hObject);

句柄这玩意儿不懂,有大大指教不(*^__^*) 

Google后发现如下两篇文章,解释的很清楚了,供参阅:

(PS. 正如先前已有很多同学写过这方面的文章,但要不是自己亲自遇到了,还真的不会在意这个问题。虽说本文只是用于收藏,只是作为一个知识点,仅供日后翻阅,这篇文章也没什么技术含量, 但还是想放在首页一下下,毕竟这个东西要是没接触过,突然横空遇到这样莫名crash的问题,可能也会一时无从下手。希望对大家有用。本人脸薄,如有人觉得不妥支一下,定然撤下。

我就硬头皮上一次了 ~\(≧▽≦)/~啦啦啦)

原文地址:https://www.cnblogs.com/anders06/p/1380001.html