Loading... # 引言 偶然间在任务管理器中发现之前写的程序(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() # 结语 在使用这种需要手动管理内存的语言时,内存管理上需要留意。 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏