进程退出时Atoms、HEVENT及LoadImage创建的HBITMAP/HICON是否自动释放?
核心结论
所有用户态进程持有的内核对象、GDI/User对象,在进程正常终止时都会被操作系统强制回收,不存在例外。不管你加载时是否带LR_SHARED参数,通过LoadImage得到的HBITMAP、HICON、HCURSOR,以及Atom、事件句柄、文件句柄、堆内存等所有进程关联资源,都会在进程退出时被内核统一清理,不会在系统中残留。
检测工具告警的本质
Deleaker这类资源泄漏检测工具报的泄漏,指的是进程运行周期内,申请的资源直到进程退出前都没有被主动释放的行为,和进程退出后系统是否回收是两个完全独立的概念。
你遇到的MFC、BCGControlBarPro框架的相关告警,属于框架设计层面的刻意行为:
- 类似
CBCGPGlobalUtils::GetStretchCursor中加载的光标这类资源,属于全局单例资源,只会在程序首次触发对应功能时加载一次,之后全程复用,不会重复创建。 - 框架默认不会主动释放这类全局资源:一来进程退出时系统会自动回收,主动释放没有实际价值;二来如果中间误释放,后续调用时还要重新加载,反而会降低性能、引入不稳定风险。这种单次加载、全程存活的资源属于可接受的"善意泄漏",不会导致运行问题。
需要主动处理的泄漏场景
只有以下场景的资源泄漏需要修复:
- 程序运行过程中会循环、反复调用
LoadImage加载非共享资源,且用完不主动释放的场景:这类泄漏会导致进程的GDI对象计数持续上涨,达到系统GDI对象上限后会触发程序崩溃,是有实际危害的。你需要针对这类场景,在资源使用完毕后调用对应的释放接口:DeleteObject释放HBITMAP、DestroyIcon释放HICON、DestroyCursor释放HCURSOR。 - 长时间运行的后台服务类程序:哪怕每次泄漏的资源量很小,长期累积也会导致资源耗尽,需要严格处理所有主动申请的资源。
补充说明:带
LR_SHARED参数加载的资源属于系统全局缓存,进程退出后不会被立即回收,系统会在其他进程加载同一份资源时直接复用,这部分资源由系统自主管理,不属于你的进程导致的泄漏,无需额外处理。
内容的提问来源于stack exchange,提问作者user3161924
相关产品推荐
相关产品推荐

