WinHttpOpen存在内存泄漏问题。

3

我一直在尝试调试程序中的内存泄漏问题,并将其缩小到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上运行代码。

运行任务管理器并监视进程内存使用情况。 - seanneko
它无法显示足够准确的信息来告诉您内存泄漏情况。请参阅https://dev59.com/93I-5IYBdhLWcg3wKVE9 - Roman R.
我刚刚尝试使用perfmon来监视进程的私有字节。它报告了相同的情况 - 私有字节每秒增加约1-2MB。 - seanneko
1个回答

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 创建后台资源,包括线程,并不立即释放它们,因此它们会不断堆积。

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

总之,在实际代码中,您不应为每个小事物创建单独的会话。一个会话可能承载多个连接和请求。


有趣!感谢您的解释。看起来很奇怪,即使在调用Close方法之后它仍然持有资源。 - seanneko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接