2010-05-12 2 views
1

내 Windows 7 상자에서이 간단한 프로그램을 사용하면 응용 프로그램의 메모리 사용이 상한없이 지속적으로 위로 올라갑니다. 필자는 필수적이지 않은 모든 것을 제거했으며 Microsoft Iphlpapi 함수 "GetIpAddrTable()"이 범인임을 분명히합니다. 각 호출에서 일부 메모리가 누수됩니다. 루프 (예 : 네트워크 인터페이스 목록의 변경 사항 확인)에서는 지속될 수 없습니다. 이 작업을 수행 할 수있는 비동기 알림 API가없는 것 같습니다. 이제이 논리를 별도의 프로세스로 분리하고 주기적으로 프로세스를 재활용해야하는 상황에 직면했습니다. 추악한 솔루션입니다.GetIpAddrTable()에서 메모리가 누수됩니다. 어떻게 해결할 수 있습니까?

아이디어가 있으십니까? 당신은 전체 if 블록과 sleep을 주석 처리하면 그냥 완성도를 위해서

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

답변

1

: 다시 ERROR_INSUFFICIENT_BUFFER와 다른 오류가 발생하는 경우, 그것을위한 누수가있을 수 있습니다이 문제에 대한 Microsoft에서 더 인정이없는 것으로 나타나지만도 로컬 IP 주소를 검색하는 API를 호출 할 때 Windows 7 (XP가 아님)에 경계가 없으면 사소한 응용 프로그램이 커집니다.

내가 지금까지 해결 한 방법은 "IP 주소를 검색하여 표준 출력으로 출력"하는 명령 줄 스위치를 사용하여 별도의 응용 프로그램 인스턴스를 시작하는 것이 었습니다. 상위 응용 프로그램에서 stdout을 긁어 내면 자식이 종료되고 누출 문제가 해결됩니다.

하지만 기껏해야 "귀찮은 문제에 대한 추악한 해결책"을 얻습니다.

1

, 무슨 메모리 사용은 어떻게됩니까? 거기에 누수가 없다면 나는 그 원인에 대해 당신이 맞다고 제안 할 것입니다.

최악의 경우, MS에보고하고 문제를 해결할 수 있는지 확인하십시오. 대부분의 버그 보고서에서 보는 것보다 더 좋은 간단한 테스트 케이스가 있습니다.

또 다른 문제는 특정 오류 조건이 아닌 NO_ERROR에 대한 오류 코드를 확인하는 것입니다. 지금이 문제를 통해 모든있었습니다

DWORD dwRetVal = GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false); 
if (dwRetVal != NO_ERROR) { 
    printf ("ERROR: %d\n", dwRetVal); 
} 
+0

감사합니다. 예, GetIpAddrTable 호출을 중지하면 코드 누수가 중지됩니다. 대체 리턴 코드를 확인하는 아이디어는 좋지만 프로덕션 코드는이를 수행합니다. 누수가 지속됩니다. 마이크로 소프트에 통보하는 것에 관해서는 ... 음, 나는 그렇게 할 공동체의 의무가 있다고 생각하지만, 제품을 출하 할 수 있도록 내 문제를 해결한다는 측면에서 볼 때 실용적이지 않습니다. 기어를 완전히 전환하려고 생각합니다. gethostname()을 호출 한 다음 gethostbyname()을 호출하여 해당 이름에 바인딩 된 IP 목록을 검색합니다. 이 자극적 인 수수께끼를 남겨 두지 만 충분해야합니다. – Stabledog

2

@Stabledog : 예를 24 시간 동안 돌렸지 만 프로그램의 커밋 크기가 무한대로 증가한 것을 관찰하지 못했습니다. 항상 1024 킬로바이트 이하였습니다. 이것은 Windows 7 (32 비트 및 서비스 팩 1 없음)에서 발생했습니다.

+0

chiming in에 감사드립니다. 몇 년 전만해도 문제의 최하부에 도달했는지 여부를 기억하지 못합니다.이 답변에 게시 된 내 솔루션은 해결 방법을 취했다는 것을 나타냅니다. 요즘에는 Windows에서 작업하지도 않으며, 노후화 된 두뇌는 그러한 것들에 대한 세부 사항을 유지할 수 없습니다! :) – Stabledog

관련 문제