完全不是MFC方面的专家,但是我被安排在一个项目中以修改我们的一个应用程序中的GUI。我正在使用CListCtrl构建对话框并看到内存问题,即使我显示的列表通常包含的行数通常不超过200行。有4列,我将使用SetItemData在每行附加一个关联的int值,以便进行过滤。
当我过滤时,我先通过调用DeleteAllItems()来重新填充列表,然后循环以仅填充通过我的过滤器的数据进行填充。当我在系统任务管理器对话框的“性能”选项卡中查看时,看到对话框打开时占用的内存。似乎比我想象的要多,但无论如何。当我过滤时,如果根据所选过滤器未显示任何内容,则根据任务管理器“性能”选项卡,系统将永远不会回收内存。当我更改过滤器以显示一些行时,我看到占用了更多的内存。我再也看不到将内存还给系统了。如果继续过滤,最终将看到内存使用率几乎达到全部使用率,并且将出现MFC弹出的“内存不足”对话框。
当我在数据的完整(未经过滤)视图中上下滚动很多时,我也看到了“内存不足”对话框。对于每次滚动,即使我没有添加任何数据,列表控件的重绘也有些慢,并且“性能”选项卡中的内存使用量会增加。
有人对这里发生的事情有感觉吗?此刻我很沮丧。以下基本上是我在代码中所做的事情。我不是要管理该视图:
m_ListCtrl.DeleteAllItems();
for (int i=0; i<mylist.size(); i++)
{
// here I get all the data from the current record in mylist, one of them being an int value iSecs.
...
// insert data item
int row = m_ListCtrl.InsertItem(i, sTimeStamp.c_str());
BOOL ok = m_ListCtrl.SetItem(i, 1, sErrorCode.c_str());
ok = m_ListCtrl.SetItem(i, 2, sErrorLevel.c_str());
ok = m_ListCtrl.SetItem(i, 3, sDescription.c_str());
// set the timestamp seconds as item data for later filtering for display
ok = m_ListCtrl.SetItemData(row, (DWORD_PTR)iSecs);
}
答案 0 :(得分:1)
调用free()(或delete)时,通常不会将堆内存返回给OS。它保留在堆中。另请参见this answer。因此,在第一个填充/删除所有操作中,您将看到分配的内存增加。但是在随后的周期中,内存使用应该相当稳定。
Microsoft的MFC库已经存在了十多年了,如果CListCtrl::DeleteAllItems()中出现内存泄漏,那应该是在90年代。
您可以在程序with a few API calls中检查内存使用情况。
内存泄漏可能是由以下行引起的:
ok = m_ListCtrl.SetItemData(row, (DWORD_PTR)iSecs);
在MFC中,项目数据是用户的清理责任。您将需要遍历列表中的每个项目以释放(或删除)用户数据,然后再调用API删除列表项目。当然,您也可以通过其他方式释放分配的数据。