gpt4 book ai didi

c++ - 物理内存量随着我释放 block 而增加

转载 作者:行者123 更新时间:2023-11-30 02:11:08 26 4
gpt4 key购买 nike

我有一段 C++ 代码按如下方式释放内存

for (int i = Pages-1; i >= NewPages; i--)
{
LPVOID p = m_Pages[i];
free(p);
}

虽然代码工作正常,但当从异常处理程序调用时,它运行得非常慢。在单步执行上述循环时查看任务管理器,进程使用的物理内存量(Mem Usage)随着每次调用 free 而增加,而虚拟内存(VM Size)保持不变。最终进程异常终止。

分配抛出异常的内存的代码如下;

for (int i = Pages; i < NewPages; i++)
{
LPVOID p = malloc(m_ElementsPerPage*m_ElementSize);
if (!p)
AfxThrowMemoryException( );
m_Pages.Add(p);
}

现在乍一看,我怀疑如果我颠倒释放循环的顺序,这样最后分配的 block 最先被释放,我可能会避免这个问题。但是,为什么进程内存使用会随着调用 free 而增加,以及为什么在有效的堆内存块上调用 free 会导致程序终止,有什么理由吗? (注意,终止很可能与调试器相关,而不是应用程序本身)。

编辑:操作系统为Windows XP SP3,编译器为MSVC++ 8

Edit2:更完整版本的代码如下;

void  MyArray::ResizeArray(int NewPages)
{
int Pages = m_Pages.GetSize();
if (NewPages != Pages)
{
if (NewPages > Pages) // Grow the page array
{
for (int i = Pages; i < NewPages; i++)
{
LPVOID p = malloc(m_ElementsPerPage*m_ElementSize);
if (!p)
AfxThrowMemoryException( );
m_Pages.Add(p);
}
} else // Shrink the page array
{
for (int i = Pages-1; i >= NewPages; i--)
{
LPVOID p = m_Pages[i];
free(p);
}
m_Pages.SetSize(NewPages);
}
}
}

最佳答案

您的分配循环从 Pages 开始计数最多 NewPages而你的释放循环从 Pages-1 开始计算下降到 NewPages .只有一个可能是正确的,取决于是否 Pages <= NewPages还是不是。

如果释放循环是错误的,那么您正在尝试释放只是随机内存值的“指针”,这可能会导致任何事情,例如程序异常终止。

除此之外,调用 free()不一定会减少程序的内存大小。这取决于 malloc() 的实现/free()这个内存在内部是如何处理的。 malloc 将以某种方式在内部管理内存,并不一定会立即将释放的任何内容返回给操作系统。它可能只是在内部将其标记为“免费”,并会在以后调用 malloc() 时重用它。 .此外,如果同一内存页上还有其他已分配的内存块,它不能将该页还给操作系统。

如果您的 malloc 实现在分配的 block 旁边存储了一些管理信息(例如 block 有多大),则使用的物理内存可能会增加,因为需要换入释放的内存。 Free 将需要读取/修改此管理信息才能完成其工作,为此需要先交换内存。

关于c++ - 物理内存量随着我释放 block 而增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3863265/

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