在我们的一个项目中调查内存链接时,我遇到了一个奇怪的问题。不知何故,当父容器超出范围并且除了小对象之外不能使用时,分配给对象的内存(shared_ptr 到对象的向量,见下文)没有完全回收。
最小的例子:当程序启动时,我可以毫无问题地分配一个 1.5Gb 的连续块。在我稍微使用了内存之后(通过创建和销毁一些小对象),我不能再进行大块分配。
测试程序:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class BigClass
{
private:
double a[10000];
};
void TestMemory() {
cout<< "Performing TestMemory"<<endl;
vector<shared_ptr<BigClass>> list;
for (int i = 0; i<10000; i++) {
shared_ptr<BigClass> p(new BigClass());
list.push_back(p);
};
};
void TestBigBlock() {
cout<< "Performing TestBigBlock"<<endl;
char* bigBlock = new char [1024*1024*1536];
delete[] bigBlock;
}
int main() {
TestBigBlock();
TestMemory();
TestBigBlock();
}
如果在循环中使用带有 new/delete 或 malloc/free 的普通指针,而不是 shared_ptr,问题也会重复。
罪魁祸首似乎是在TestMemory()之后,应用程序的虚拟内存停留在827125760(不管我调用多少次)。因此,没有足够大的免费 VM regrion 来容纳 1.5 GB。但我不确定为什么——因为我肯定会释放我使用的内存。是否有一些“性能优化”CRT 可以最大限度地减少操作系统调用?
环境是 Windows 7 x64 + VS2012 + 32 位应用程序,没有 LAA