在解决应用程序中的内存泄漏问题时,我发现了另一种我担心的现象。当重复地在堆(new和delete)上分配和释放大量对象时,进程的工作集似乎随着每个循环而不断增加。我在Windows 7上使用MS Visual Studio 2013做了一个例子。
这是我用来显示工作集大小的函数:
#include <windows.h>
#include <Psapi.h>
size_t getWorkingSetInBytes()
{
size_t result = 0;
long lProcessId = GetCurrentProcessId();
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
lProcessId);
PROCESS_MEMORY_COUNTERS memoryInfo;
GetProcessMemoryInfo(hProcess, &memoryInfo, sizeof(memoryInfo));
result = size_t(memoryInfo.WorkingSetSize);
CloseHandle(hProcess);
return result;
}
我有一个简单的示例类:
class A
{
public:
long m_one;
long m_two;
};
使用new / delete的功能:
void loopWithNew(size_t loops, size_t objects)
{
for(size_t i = 0; i < loops; ++i)
{
{
std::vector<A*> vecA;
for(size_t j = 0; j < objects; ++j)
{
A* a = apsnew A();
a->m_one = 42;
a->m_two = 43;
vecA.push_back(a);
}
for(auto iter = vecA.begin(); iter != vecA.end(); ++iter)
{
delete *iter;
}
}
std::cout << "working set in bytes after deleting all objects: " << getWorkingSetInBytes() << std::endl;
}
}
一个不使用new / delete:
void loopWithoutNew(size_t loops, size_t objects)
{
for(size_t i = 0; i < loops; ++i)
{
{
std::vector<A> vecA(objects);
for(size_t j = 0; j < objects; ++j)
{
vecA[j].m_one = 42;
vecA[j].m_two = 43;
}
}
std::cout << "working set in bytes after deleting all objects: " << getWorkingSetInBytes() << std::endl;
}
}
主要来自:
int main(int argc, char** argv)
{
size_t loops = 10;
size_t objects = 10000000;
size_t beforeStart = getWorkingSetInBytes();
std::cout << "working set before start: " << beforeStart << std::endl;
std::cout << std::endl << "loops with new: " << std::endl;
loopWithNew(loops, objects);
std::cout << std::endl << "loops without new: " << std::endl;
loopWithoutNew(loops, objects);
}
程序产生以下输出:
working set before start: 2396160
loops with new:
working set in bytes after deleting all objects: 3923968
working set in bytes after deleting all objects: 3813376
working set in bytes after deleting all objects: 3964928
working set in bytes after deleting all objects: 3866624
working set in bytes after deleting all objects: 3923968
working set in bytes after deleting all objects: 3989504
working set in bytes after deleting all objects: 4059136
working set in bytes after deleting all objects: 4067328
working set in bytes after deleting all objects: 4210688
working set in bytes after deleting all objects: 4259840
loops without new:
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
working set in bytes after deleting all objects: 4259840
虽然带有new / delete的循环会随着时间的推移而增加工作集,但没有new / delete的版本似乎不会增加工作集。这带来了多个相关问题: