在我的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;
}
答案 0 :(得分:2)
@Stabledog: 我已经运行了你的例子,未修改,24小时,但没有观察到程序的Commit Size无限增加。它总是低于1024千字节。这是在Windows 7(32位,没有Service Pack 1)上。
答案 1 :(得分:1)
为了完整起见,如果您注释掉整个if
块和sleep
,内存使用情况会怎样?如果那里没有泄漏,那么我建议你对造成它的原因是正确的。
最糟糕的情况是,向MS报告,看看他们是否可以修复它 - 你有一个很好的简单测试用例,这比我在大多数bug报告中看到的更多。
您可能想要尝试的另一件事是针对NO_ERROR
检查错误代码,而不是特定的错误情况。如果您收到的错误与ERROR_INSUFFICIENT_BUFFER
不同,则可能存在泄漏:
DWORD dwRetVal = GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false);
if (dwRetVal != NO_ERROR) {
printf ("ERROR: %d\n", dwRetVal);
}
答案 2 :(得分:1)
我现在已经解决了这个问题:似乎微软没有就这个问题做出任何回应,但是在调用任何API时,即使是一个简单的应用程序也会在Windows 7(不是XP)上无限制地增长。检索本地IP地址。
所以我解决它的方式 - 现在 - 用一个特殊的命令行开关启动我的应用程序的单独实例,告诉它“检索IP地址并将它们打印到stdout”。我在父应用程序中刮掉stdout,孩子退出并且泄漏问题得到解决。
但它充其量只能赢得“讨厌烦人的问题”。