我一直在尝试调试程序中的内存泄漏,并将其缩小到WinHttp通信。我已经能够在以下测试代码中重现该问题:
#include <windows.h>
#include "winhttp.h"
void main() {
while (1) {
HINTERNET send_session = WinHttpOpen(L"asdf", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
WinHttpCloseHandle(send_session);
}
}
运行几秒钟后,程序已经使用了超过20MB的内存。它为什么这样做? The API表示在不再需要句柄后需要调用WinHttpCloseHandle - 我正在这样做。
我正在使用Arch Linux上的mingw32编译,并在Windows 7上运行代码。
答案 0 :(得分:4)
如果你稍微修改一下代码,你会看到发生了什么。
int _tmain(int argc, _TCHAR* argv[])
{
for(INT n = 0; n < 1000000; n++)
{
if(!(n % 10000))
_tprintf(_T("%d\n"), n / 10000);
HINTERNET send_session = WinHttpOpen(L"asdf", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
WinHttpCloseHandle(send_session);
}
_tprintf(_T("Done\n"));
Sleep(INFINITE);
return 0;
}
随着创建/关闭一百万个会话,您将看到计数器攀升。 API会创建包含线程的后台资源,并且不会立即释放它们,因此它们会不断堆积。
但是,只要您停止创建新会话并让它有几秒钟的空闲时间,您就会看到所有内存都被释放。
最重要的是,在实际代码中,您不应为每件小事创建单独的会话。一个会话可能正在托管多个连接和请求。