gpt4 book ai didi

c++ - 为什么删除的内存无法重用

转载 作者:可可西里 更新时间:2023-11-01 18:21:50 27 4
gpt4 key购买 nike

我在装有 MSVC 9.0 的 Windows 7 上使用 C++,并且还能够在装有 MSVC 9.0 的 Windows XP SP3 上进行测试和重现。

如果我分配 1 GB 的 0.5 MB 大小的对象,当我删除它们时,一切都正常并且按预期运行。但是,如果我在删除它们时分配 1 GB 的 0.25 MB 大小的对象,内存将保留(Address Space Monitor 中的黄色)并且从那时起只能用于小于 0.25 MB 的分配。

这个简单的代码将允许您通过更改类型定义的结构来测试这两种情况。在分配和删除结构后,它将分配 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 标记的结构的大小

Quarter Meg Half Meg

对我来说,这似乎是一个相当严重的问题,许多人可能正在遭受这个问题,但他们甚至都不知道。

  • 那么这是设计使然还是应该将其视为错误?
  • 我能否让较小的已删除对象实际上可以免费供较大的分配使用?
  • 出于好奇,Mac 或 Linux 机器是否遇到同样的问题?

最佳答案

我不能肯定地说是这种情况,但这看起来确实像内存碎片(以多种形式之一)。分配器 (malloc) 可能会保留不同大小的存储桶以实现快速分配,在您释放内存后,它不会直接将其返回给操作系统,而是保留存储桶以便以后可以从中处理相同大小的分配同样的内存。如果是这种情况,内存将可用于相同大小的进一步分配。

这种类型的优化通常对对象禁用,因为它需要保留内存,即使不使用也是如此。如果阈值介于您的两个尺寸之间,则可以解释该行为。

请注意,虽然您可能认为这很奇怪,但在大多数程序(不是测试,而是现实生活)中,内存使用模式是重复的:如果您请求 100k block 一次,通常情况下您会再来一遍。保持内存保留可以提高性能,并且实际上可以减少来自同一个存储桶的所有请求的碎片。

如果您想花一些时间,可以通过分析行为来了解分配器的工作原理。编写一些测试,获取大小 X,释放它,然后获取大小 Y,然后显示内存使用情况。固定 X 的值并使用 Y。如果从相同的桶中授予两种大小的请求,您将不会有保留/未使用的内存(左图),而当从不同的桶中授予大小时,您将看到右图效果。

我通常不为 Windows 编写代码,我什至没有 Windows 7,所以我不能肯定地说是这种情况,但看起来确实如此。

关于c++ - 为什么删除的内存无法重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5416513/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com