我反复调用 fuct 10000次,监控其内存。有明显增长。不知道哪里没有释放。
首先,没有全局变量,所有变量都应该在 fuct() 结束后释放
其实,如果注释掉
if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK)
return 0;
那么没有泄露,请高手帮忙看一下,哪里漏了。内存增长为 24576 b以下是代码:int main()
{
printf("hello world\n");
uint64_t mem, vmem; CoInitialize(NULL); //必须要这句初始化
for(int i = 0;i < 10000;i++)
{
fuct();
get_memory_usage(&mem, &vmem);
printf("内存使用: %u 字节\n", mem);
Sleep(1);
} CoUninitialize();
return 1;
}int fuct()
{
SHDocVw::IShellWindowsPtr m_spSHWinds; //定义接口变量 //////////get the broswer
if (m_spSHWinds == NULL){
if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) return 0;
}
if(m_spSHWinds != NULL)
{
m_spSHWinds->Release();
}
return 1;
}
首先,没有全局变量,所有变量都应该在 fuct() 结束后释放
其实,如果注释掉
if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK)
return 0;
那么没有泄露,请高手帮忙看一下,哪里漏了。内存增长为 24576 b以下是代码:int main()
{
printf("hello world\n");
uint64_t mem, vmem; CoInitialize(NULL); //必须要这句初始化
for(int i = 0;i < 10000;i++)
{
fuct();
get_memory_usage(&mem, &vmem);
printf("内存使用: %u 字节\n", mem);
Sleep(1);
} CoUninitialize();
return 1;
}int fuct()
{
SHDocVw::IShellWindowsPtr m_spSHWinds; //定义接口变量 //////////get the broswer
if (m_spSHWinds == NULL){
if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) return 0;
}
if(m_spSHWinds != NULL)
{
m_spSHWinds->Release();
}
return 1;
}
回复 2楼,系统如果自动回收,那么也不应该一直增长呀,内存变化应该是一个曲线
回复 3楼,为什么要两次调用sleep呢?
m_spSHWinds->Release();
回复 6#, 就是因为 m_spSHWinds 调用的是微软的接口,才会弄不清楚哪里内存漏了。
我用的 VC6,超级古老的版本,操作的是IE6.所以是系统的bug不太可能吧。求那位帮帮忙吧,我的插件内存总是增加,用不了了。
还是其他的地方看看,如果是ATL环境下,_ATL_DEBUG_QI和_ATL_DEBUG_INTERFACES两个东西可以用一下?
因为浏览器数量与title是不断更新的,所以才需要不断获取。另外,我使用的ATL,请教以下问题:
1, 我调用一次 CreateInstance,那么当浏览器数量和title发生变化后,m_spSHWinds 是否会发生变化。可以调用哪个方法进行刷新呢?
2, _ATL_DEBUG_QI和_ATL_DEBUG_INTERFACES 怎么用,能不能给个例子
http://www.codeguru.com/cpp/com-tech/atl/atl/article.php/c87/How-does-ATLDEBUGINTERFACES-work.htm
但是调试第三方控件不一定好使
另外注意不要反复的去create,理论上虽然当引用计数为0时,release之后会delete这段内存,但是这不是我们可控的,它可能基于其他的考虑会存留相当一段时间,当然你可以试试cofreeunusedlibrary,不过我认为也没什么效果。
我能想到的比较简单的做法是进程外去加载这种反复的行为,然后kill掉进程。
{
SHDocVw::IShellWindowsPtr m_spSHWinds; //定义接口变量
//////////get the broswer
if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK)
return 0;
return 1;
}
回复 xuddk727:get_memory_usage是我写的用来监控内存的函数。如果我要更新浏览器的状态,不反复获取,还可以用什么方法呢?
回复 tiger9991:我的安排是:监控当前程序执行时的内存变化,发现内存一直在涨,这个难道不能认为是内存泄露吗?
回复 Saleayas: 如果不release,不是泄露的更加厉害吗