我在带有 MSVC 9.0 的 Windows 7 上使用 C++,并且还能够在带有 MSVC 9.0 的 Windows XP SP3 上进行测试和重现。
如果我分配 1 GB 的 0.5 MB 大小的对象,当我删除它们时,一切正常并且按预期运行。但是,如果我在删除它们时分配 1 GB 的 0.25 MB 大小的对象,则内存保持保留状态(地址空间监视器中的黄色),从那时起将只能用于小于 0.25 MB 的分配。
这个简单的代码将让您通过更改哪个结构是 typedef'd 来测试这两种情况。在分配并删除结构后,它将分配 1 GB 的 1 MB 字符缓冲区,以查看字符缓冲区是否会使用结构曾经占用的内存。
struct HalfMegStruct
{
HalfMegStruct():m_Next(0){}
/* return the number of objects needed to allocate one gig */
static int getIterations(){ return 2048; }
int m_Data[131071];
HalfMegStruct* m_Next;
};
struct QuarterMegStruct
{
QuarterMegStruct():m_Next(0){}
/* return the number of objects needed to allocate one gig */
static int getIterations(){ return 4096; }
int m_Data[65535];
QuarterMegStruct* m_Next;
};
// which struct to use
typedef QuarterMegStruct UseType;
int main()
{
UseType* first = new UseType;
UseType* current = first;
for ( int i = 0; i < UseType::getIterations(); ++i )
current = current->m_Next = new UseType;
while ( first->m_Next )
{
UseType* temp = first->m_Next;
delete first;
first = temp;
}
delete first;
for ( unsigned int i = 0; i < 1024; ++i )
// one meg buffer, i'm aware this is a leak but its for illustrative purposes.
new char[ 1048576 ];
return 0;
}
您可以在下面看到我在Address Space Monitor中的结果。让我强调一下,这两个最终结果之间的唯一区别是分配给 1 GB 标记的结构的大小。
对我来说,这似乎是一个相当严重的问题,许多人可能正在遭受痛苦,甚至不知道。
- 那么这是设计使然还是应该将其视为错误?
- 我可以让较小的已删除对象实际上可以免费供较大的分配使用吗?
- 出于好奇,Mac 或 Linux 机器会遇到同样的问题吗?