WinHttp打开泄漏内存

WinHttpOpen leaking memory

本文关键字:内存 泄漏 WinHttp      更新时间:2023-10-16

我一直在尝试调试程序中的内存泄漏,并将其缩小到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 的内存。为什么要这样做?API 指出,在不再需要句柄后,您需要调用 WinHttpCloseHandle - 我正在这样做。

我在 Arch Linux 上使用 mingw32 进行编译,并在 Windows 7 上运行代码。

如果你稍微修改一下代码,你会看到发生了什么。

int _tmain(int argc, _TCHAR* argv[])
{
    for(INT n = 0; n < 1000000; n++)
    {
        if(!(n % 10000))
            _tprintf(_T("%dn"), 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("Donen"));
    Sleep(INFINITE);
    return 0;
}

随着创建/关闭一百万个会话,您将看到计数器不断攀升。API 创建包括线程在内的后台资源,并且不会立即释放它们,因此它们会不断堆积。

但是,一旦您停止创建新会话并让它有几秒钟的空闲时间 - 您将看到所有内存都已释放。

底线是,在实际代码中,您不应该为每个小事情创建一个单独的会话。一个会话可能托管多个连接和请求。