引言
偶然间在任务管理器中发现之前写的程序(KMUCounter)句柄很高,众所周知,句柄就相当于一个索引,如果持续增长可能导致程序句柄达到上限影响稳定性,并且影响系统性能。

解决过程
首先观察变化趋势,发现是每秒增加1,在代码中找相关的计时器,找了找也没发现什么问题,因为时间是动态设置的,所以也不太好找。(主要是没耐心了),谁想到黑盒更直观的找到了问题。
准备windbg,附加到进程上,开启句柄追踪堆栈(!htrace -enable),放行之后等一会儿然后再暂停,执行!htrace -diff,查看差异,虽然有很多,但是基本上都是重复的,发现存在OpenProcess,这就使我警觉起来,因为打开进程肯定会创建句柄,如果不销毁的话,那就会越聚越多。

回看那部分代码部分,果然没有CloseHandle,加上重新编译,解决问题。
需要警惕的方法
一、Windows 原生 API(必须手动释放)
CreateFile → CloseHandle 或 CloseHandle(文件句柄)。
OpenProcess → CloseHandle(打开进程)。
CreateThread / CreateRemoteThread → CloseHandle(创建线程)
CreateProcess → PROCESS_INFORMATION.hProcess / hThread 都要 CloseHandle。
CreateFileMapping → UnmapViewOfFile + CloseHandle(mapping)`。
FindFirstFile → FindClose(查文件)
GetDC(hWnd) → ReleaseDC(hWnd, hdc)
CreateCompatibleDC → DeleteDC
CreateCompatibleBitmap / CreateBitmap / CreateDIBSection → DeleteObject
SelectObject(hdc, hOld) → 在删除位图等 GDI 对象前要 SelectObject 恢复旧对象(否则不能删除)
LoadLibrary → FreeLibrary(DLL 引用计数)
OpenEvent, OpenSemaphore → CloseHandle
二、GDI / USER 相关(图形/窗口句柄)
CreatePen, CreateBrush, CreateFont, CreateBitmap, CreateCursor, CreateIcon → DeleteObject / DestroyCursor / DestroyIcon`
GetWindowTextBuffer(分配内存)注意释放你自己分配的内存。
三、网络 / 套接字 / Winsock
socket() → closesocket()
WSAStartup() → WSACleanup()(匹配)
四、文件 / C 运行时
fopen() → fclose()
fread/fwrite 最后需要 fclose / fflush
std::ifstream/ofstream:确保析构或 close()
结语
在使用这种需要手动管理内存的语言时,内存管理上需要留意。


评论 0
还没有评论,来说点什么吧。