【问题标题】:WinHttpOpen leaking memoryWinHttpOpen 内存泄漏
【发布时间】:2012-09-21 02:20:35
【问题描述】:

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

【问题讨论】:

  • 运行任务管理器,查看进程内存使用情况。
  • 它没有向您显示任何足够准确的信息来判断内存泄漏。见stackoverflow.com/questions/1984186/…
  • 我刚刚尝试使用 perfmon 来监控进程的私有字节。它报告同样的事情 - 私有字节每秒增加约 1-2MB。

标签: c++ c memory memory-leaks winhttp


【解决方案1】:

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

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;
}

随着创建/关闭 100 万个会话,您会看到计数器攀升。 API会创建包括线程在内的后台资源,并不会立即释放,所以不断堆积。

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

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

【讨论】:

  • 有趣!感谢您的解释。即使在调用 Close 之后它仍然持有资源,这似乎很奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 2013-01-20
  • 2011-10-31
  • 2019-08-10
  • 2013-06-24
  • 2011-03-22
  • 2015-04-20
相关资源
最近更新 更多