3

I've been trying to debug a memory leak in my program, and have narrowed it down to the WinHttp comms. I've been able to reproduce the problem in the following test code:

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

After running this for a few seconds, the program is already using over 20MB memory. Why is it doing this? The API states that you need to call WinHttpCloseHandle after the handle is no longer needed - I'm doing that.

I'm compiling using mingw32 on Arch Linux, and running the code on Windows 7.

seanneko
  • 33
  • 3
  • Running task manager and watching the process memory usage. – seanneko Sep 29 '12 at 13:17
  • It does not show you anything accurate enough to tell memory leaks. See http://stackoverflow.com/questions/1984186/what-is-private-bytes-virtual-bytes-working-set – Roman R. Sep 29 '12 at 13:41
  • I've just tried using perfmon to monitor the private bytes of the process. It reports the same thing - private bytes going up by around 1-2MB per second. – seanneko Sep 29 '12 at 13:46

1 Answers1

4

If you modify the code a bit, you will see what is happening.

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

Along with creating/closing one million of sessions you will see counters climbing up. The API creates background resources including threads and does not release them immediately, so they keep piling up.

However as soon as you stop creating new sessions and let it have a few seconds of idle time - you will see all that memory is released.

The bottom line is that in real code you should not create a separate session for every small thing. One session might be hosting multiple connections and requests.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • Interesting! Thanks for the explanation. It seems strange that it holds the resources even after Close has been called. – seanneko Sep 29 '12 at 14:13