GetIpAddrTable () утечки памяти. Как решить это? - PullRequest
1 голос
/ 12 мая 2010

На моем компьютере с Windows 7 эта простая программа вызывает непрерывное увеличение использования памяти приложением, без верхней границы. Я удалил все несущественное, и кажется очевидным, что виновником является функция Microsoft Iphlpapi «GetIpAddrTable ()». При каждом вызове происходит утечка памяти. В цикле (например, проверка изменений в списке сетевых интерфейсов) это неустойчиво. Похоже, что не существует API асинхронных уведомлений, который мог бы выполнять эту работу, поэтому теперь я, возможно, столкнулся с необходимостью изолировать эту логику в отдельный процесс и периодически перерабатывать процесс - некрасивое решение.

Есть идеи?

// IphlpLeak.cpp - demonstrates that GetIpAddrTable leaks memory internally:  run this and watch
// the memory use of the app climb up continuously with no upper bound.
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <Iphlpapi.h>
#pragma comment(lib,"Iphlpapi.lib")

void testLeak() {
    static unsigned char buf[16384];
    DWORD dwSize(sizeof(buf));
    if (GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false) == ERROR_INSUFFICIENT_BUFFER)
    {
        assert(0); // we never hit this branch.
        return;
    }
}
int main(int argc, char* argv[]) {
    for ( int i = 0; true; i++ )    {
        testLeak();
        printf("i=%d\n",i); 
        Sleep(1000);
    }
    return 0;
}

Ответы [ 3 ]

2 голосов
/ 29 мая 2012

@ Stabledog: я запускал ваш пример без изменений в течение 24 часов, но не заметил, что размер коммитов программы увеличивался бесконечно.Он всегда оставался ниже 1024 килобайт.Это было в Windows 7 (32-разрядная версия и без пакета обновления 1).

1 голос
/ 02 июня 2010

Теперь я уже во всем разбираюсь: кажется, что от Microsoft нет подтверждения по этому поводу, но даже тривиальное приложение растет без границ в Windows 7 (но не в XP) при вызове любого API, получить локальные IP-адреса.

Таким образом, пока я решил это - запустить отдельный экземпляр моего приложения с помощью специального переключателя командной строки, который сообщает ему: «получить IP-адреса и распечатать их на стандартный вывод». Я очищаю стандартный вывод в родительском приложении, дочерний процесс завершается, и проблема утечки устранена.

Но это в лучшем случае выигрывает "чертовски безобразное решение надоедливой проблемы".

1 голос
/ 12 мая 2010

Просто ради полноты, что произойдет с использованием памяти, если вы закомментируете весь блок if и sleep? Если там нет утечки, то я бы сказал, что вы правы относительно того, что ее вызывает.

В худшем случае, сообщите об этом MS и посмотрите, смогут ли они это исправить - у вас есть хороший простой тестовый пример, который работает больше, чем я вижу в большинстве отчетов об ошибках.

Еще одна вещь, которую вы можете попробовать, это проверить код ошибки по NO_ERROR, а не по конкретному условию ошибки. Если вы получите ошибку, отличную от ERROR_INSUFFICIENT_BUFFER, возможно, для этого есть утечка:

DWORD dwRetVal = GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false);
if (dwRetVal != NO_ERROR) {
    printf ("ERROR: %d\n", dwRetVal);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...