我有一个应用程序在这段时间内运行得更慢(几天后非常显着).
我仍然不知道这是从哪里来的,但我在任务管理器中看到,该应用程序不断消耗更多内存(工作集和提交大小)。
我有特殊的跟踪来可视化到不同输出窗格的跟踪。 我只需将跟踪添加到一个或多个不同的CStringList
即可做到这一点。 像这个代码示例
//////////////////////////////////////////////////////////////////////////
// TRACE HW_MESSAGES
void TRACE_HW(LPCTSTR pszstring)
{
CHwTestApp* pApp = &theApp;
if (pApp)
return;
TRACE(pszstring);
if (theApp.mStrHwList.GetCount() > kMAXTRACEs)
{
CString ob = theApp.mStrHwList.RemoveHead();
}
theApp.mStrHwList.AddTail(pszstring);
}
我的问题CStringList
可以通过调用RemoveHead
和AddTail
来变得更伟大吗?
他是立即在内部压缩他使用的物理记忆还是延迟?
发布的代码不会泄漏内存。RemoveHead()
的特定CStringList
重载会将所有权从容器中传递出去,并且本地ob
对象会立即被销毁。
AddTail()
创建传入字符串指针的CString
副本,并将该副本传递到CStringList
中。因此,您可以无限期地运行以下代码,而不会增加内存:
while (true) {
CString str = _T("Test trace entry");
TRACE_HW(str.GetString());
}
这里的关键点是TRACE_HW
不会拥有pszstring
所指向的内存的所有权。只要调用方确保清理它,一切都很好(这就是本地CString
对象所做的)。
但是,如果将其更改为以下内容:
while (true) {
TCHAR* str = new TCHAR[256];
TRACE_HW(str);
}
事情开始发生变化。这是分配内存,将指针传递到仅观察内存的TRACE_HW
,但没有人清理它。
在所有条件相同的情况下,问题在于TRACE_HW
的调用者,而不是TRACE_HW
本身。
嗯,有点,无论如何。TRACE_HW
的功能签名肯定会邀请客户假设他们正在假冒所有权。C++中的指针参数通常对所有权转让进行建模。如果只想表达作为观察者的属性,则const
引用更合适。
如果TRACE_HW
具有以下签名:
void TRACE_HW(CString const& msg)
对于客户来说,更明显的是,他们保留对传递给接口进行检查的对象的责任。当调用过期时,他们仍然负责处理实际对象。
CString ob = ...
立即在范围内销毁。因此,这不是泄漏原因。
https://learn.microsoft.com/en-us/windows/win32/directshow/cgenericlist-removehead
但是,根据此,RemoveHead
返回一个 OBJECT*。去哪儿了?它被 CString 复制了,但原始对象*被保留了?