为什么删除的内存无法使用? C++

发布于 2024-10-25 08:31:22 字数 1673 浏览 2 评论 0原文

我有一个 200 MB XML 文件,正在使用 TinyXML 加载。我的问题是,当TinyXML对象被销毁时,它使用的内存将不会被重用。我使用过在其他项目中使用过的内存泄漏检测器,并手动单步执行代码,但未能发现任何内存泄漏,因此我不怀疑泄漏的内存是问题所在。

此代码将重现该问题:

#include <iostream>
#include <tinyxml.h>

int main()
{
    char* filename = "../LargeFile.xml";

    {
        TiXmlDocument targetDoc( filename );
        targetDoc.LoadFile();
    }

    char* buf = new char[ 524288000 ];
    delete [] buf;

    return 0;
}

使用 地址空间监视器 我可以在 LoadFile()< /code> 有一大块红色,然后 targetDoc 被破坏后就全是黄色了。然后,当分配最终的 char buf 时,它会显示为红色,但位于绿色空间的顶部,而不是从 TinyXML 中释放的黄色。如果尝试分配比绿色地址空间更多的缓冲区,应用程序将崩溃(内存不足)。这可以在下图中看到。

加载后 卸载后 Char Buffer Allocation

根据地址空间监控页面“空闲地址空间显示为绿色,保留地址显示为黄色并使用(提交)的内存区域为红色” 那么,根据地址空间监视器,为什么 TinyXML 释放的内存保持“保留”状态。什么会导致这种情况发生,我该如何阻止它?

编辑:

“您正在分配大缓冲区吗?如果是这样,那么黄色空间中可能存在内存碎片,并且没有地方可以分配大的连续缓冲区”

好问题然而,这表明 TinyXML 存在内存泄漏,而我的任何工具都没有表明存在内存泄漏。

更新

我制作了无限分配整数的循环,最终似乎使用了所有黄色空间。然而更大的分配不使用它。这向我表明,在tinyXML解析xml文件的过程中,堆中散布着一些小泄漏,它以这样的方式对堆进行碎片化,只有足够小的对象才能容纳在泄漏之间,才能在黄色空间中分配。因此,我在 TinyXML 中寻找了更长时间、更努力的漏洞,但仍然没有找到任何漏洞。一切似乎都得到了正确的释放,这让我又回到了最初的困惑状态。

我不知道如何解释这个问题。

字符缓冲区分配 字符缓冲区分配2 字符缓冲区分配3

I have a 200 MB XML file that I am loading using TinyXML. My problem is that when the TinyXML object is destroyed, the memory it used will not be reused. I have used a memory leak detector that I have used in other projects, and have manually stepped through the code and have not been able to find any memory leaks, so I don't suspect that leaked memory is the problem.

This code will reproduce the problem:

#include <iostream>
#include <tinyxml.h>

int main()
{
    char* filename = "../LargeFile.xml";

    {
        TiXmlDocument targetDoc( filename );
        targetDoc.LoadFile();
    }

    char* buf = new char[ 524288000 ];
    delete [] buf;

    return 0;
}

Using Address Space Monitor I can see that after LoadFile() there is a large chunk of red, then after targetDoc is destroyed it is all yellow. Then when the final char buf is allocated it appears in red but over the top of green space rather than the yellow freed from TinyXML. If try to allocate more buffers than there is green address space the application will crash(out of memory). This can be seen in the images below.

After Load
After Unload
Char Buffer Allocation

According to the Address space monitor page "Free address space is shown in green, reserved addresses in yellow and used (committed) memory regions in red" So why is the memory that is freed by TinyXML staying "reserved" according to Address Space Monitor. What can cause that to happen, and how do I stop it?

EDIT:

"Are you allocating large buffers? If so, then there may be memory fragmentation in the yellow space and there's nowhere that a large contiguous buffer can be allocated"

Great question however this would indicate that TinyXML has a memory leak and none of my tools have shown there to be one.

UPDATE

I made loop that endlessly allocated ints, which eventually appeared to used all the yellow space. However larger allocations don't use it. This indicated to me that there were small leaks that were getting littered through the heap during the parsing of the xml file by tinyXML which fragments the heap in such a way that only objects small enough to fit between the leaks could be allocated in the yellow space. So I searched longer and harder for leaks in TinyXML and still did not find any. Everything seems to be getting freed up correctly, which brings me back to my initial state of confusion.

I am at a loss to explain the problem.

Char Buffer Allocation
Char Buffer Allocation2
Char Buffer Allocation3

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小女人ら 2024-11-01 08:31:23

您是否确实看到了内存问题的任何其他迹象?保留内存表示该地址范围是操作系统保留的,但实际没有物理内存在使用。没什么好担心的。当您下次需要内存时,它将首先来自该保留空间。

Are you actually seeing any other indications of memory issues? Reserved memory indicates that the address range is reserved from the OS, but there is no physical memory actually in use. It is nothing to worry about. When you next need memory, it will first come from that reserved space.

善良天后 2024-11-01 08:31:23

当 free() 完成时,大多数操作系统实际上不会将内存释放回操作系统(Linux 有时会进行大量释放)。相反,应用程序使用操作系统 sbreak() 函数来增加内存,保持“高水位线”。只要您为每个 malloc() 执行 free() 操作,内存就不会泄漏,并且将来的分配将来自同一内存。当然,TinyXML 内部可能有意或无意地没有执行此类匹配释放,例如:

  • TinyXML 类中的某些函数或由它调用的函数可能有一个静态局部指针变量,该变量被初始化为指向新分配的堆当函数第一次被调用时。如果在其他例程为更多瞬态数据分配大量内存之后发生这种情况,那么即使在释放后一个内存之后,静态指针的分配也可能会导致一些碎片,从而阻止在回收空间中分配巨大的连续块。

Most OSes don't actually release memory back to the OS when a free() is done (Linux does sometimes for large deallocations). Instead, application's use the OS sbreak() function to grow memory, maintaining a "high water mark". As long as you're doing the free() for each malloc() then memory's not being leaked, and future allocations will come from the same memory. Of course, it may be that something inside TinyXML's not doing such matching frees, deliberately or otherwise, e.g.:

  • some function in the TinyXML class, or called by it, could have a static local pointer variable that is initialised to point to newly allocated heap when the function is first called. If that happens after other routines have allocated a lot of memory for more transient data, then even after the latter memory is freed the static pointer's allocation may cause some fragmentation, preventing allocation of a huge contiguous block in the reclaimed space.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文