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 でコードを実行しています。

4

1 に答える 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;
}

100 万回のセッションを作成/終了すると、カウンターが上昇します。API は、スレッドを含むバックグラウンド リソースを作成し、すぐに解放しないため、山積みになります。

ただし、新しいセッションの作成を停止して数秒のアイドル時間を持つとすぐに、すべてのメモリが解放されることがわかります。

肝心なのは、実際のコードでは、小さなことごとに個別のセッションを作成するべきではないということです。1 つのセッションが複数の接続と要求をホストしている場合があります。

于 2012-09-29T14:04:04.797 に答える