Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 堆碎片和windows内存管理器_C++_Windows_Memory Management - Fatal编程技术网

C++ 堆碎片和windows内存管理器

C++ 堆碎片和windows内存管理器,c++,windows,memory-management,C++,Windows,Memory Management,我的程序内存碎片有问题,过了一段时间后无法分配非常大的内存块。我已经阅读了这个论坛上的相关帖子——主要是一篇。我还有一些问题 我一直在使用内存空间来获取内存的图片。我编写了一个包含cin>>var的单行程序;并拍摄了一张记忆照片: 在顶部,绿色表示空白,黄色表示已分配,红色表示已提交。我的问题是右边分配的内存是什么?它是主线程的堆栈吗?这个内存不会被释放,它会分割我需要的连续内存。在这个简单的单行程序中,拆分没有那么糟糕。我的实际程序有更多的东西在地址空间中间分配,我不知道它是从哪里来的。我还

我的程序内存碎片有问题,过了一段时间后无法分配非常大的内存块。我已经阅读了这个论坛上的相关帖子——主要是一篇。我还有一些问题

我一直在使用内存空间来获取内存的图片。我编写了一个包含cin>>var的单行程序;并拍摄了一张记忆照片:

在顶部,绿色表示空白,黄色表示已分配,红色表示已提交。我的问题是右边分配的内存是什么?它是主线程的堆栈吗?这个内存不会被释放,它会分割我需要的连续内存。在这个简单的单行程序中,拆分没有那么糟糕。我的实际程序有更多的东西在地址空间中间分配,我不知道它是从哪里来的。我还没有分配内存

  • 我怎样才能解决这个问题?我想换成nedmalloc或dlmalloc。然而,这只适用于我自己明确分配的对象,而图片中显示的分割不会消失?或者有没有办法用另一个内存管理器替换CRT分配

  • 对于对象,有没有用于C++的NeDimoLoc的包装器,所以我可以使用新的和Delphi来分配对象?< /P> < /LI>
    谢谢。

    可能是可执行文件吗?它必须被加载到某个地址空间


    至于2,它很容易覆盖全局新建和删除函数。。。只需定义它们。

    我假设您经常分配和取消分配大小不同的对象,这就是导致内存碎片问题的原因

    有各种各样的策略来解决这些问题;如果您提到的不同内存管理器可以为您解决碎片问题,那么它们可能会有所帮助,但这需要对碎片的根本原因进行更多的分析。例如,如果您经常分配三种或四种类型的对象,而这些对象往往会恶化内存碎片问题,那么您可能希望将这些对象放入它们自己的内存池中,以便能够重用正确大小的内存块。这样,您应该有一组适合这个特定对象的可用内存块,并防止常见的情况,即对象X的分配会分割一个足够大的内存块,以容纳Y,从而突然无法再分配任何Y

    至于(2),我不知道nedmalloc的包装器(坦白地说,我对nedmalloc不是很熟悉),但您可以非常轻松地创建自己的包装器,因为您可以创建特定于类的运算符new和delete,甚至可以重载/替换全局运算符new和delete。我不太喜欢后者,但如果您的分配“热点”由少数几个类组成,则通常很容易使用它们自己的、特定于类的运算符new和delete对它们进行改装


    也就是说,nedmalloc宣称自己是标准malloc/free的替代品,至少是MS编译器的替代品,我认为C++运行时库会将新的/DELL转发到MALOC/FLUE,因此它可能只是一个使用NEDMOLLC.< /P> > P>构建可执行文件的例子。找出程序中内存分配的最佳方法是使用调试器。每个加载的DLL和可执行文件本身都有分配,所有这些都是虚拟内存片段。此外,使用C/C++库和Windows API将导致在应用程序中创建堆,这至少会保留一块虚拟内存

    例如,您可以使用VirtualAlloc在一个相对较小的程序中保留大量虚拟内存,结果发现VirtualAlloc失败,或者应用程序在稍后尝试加载新DLL时失败(等等)。您也无法始终控制加载哪些DLL以及在何处加载。许多A/V和其他产品会在所有正在运行的进程启动时将DLL注入其中。当这种情况发生时,这些DLL通常在加载地址上有优先选择权——也就是说,它们的编译/链接默认值可能会被授予。在一个典型的32位Windows应用程序的可用2GB虚拟地址空间中,如果DLL在该地址空间的中间加载SMAK,则可以获得的最大单个分配/保留将小于1 GB。 如果使用windbg,可以看到哪些内存区域被占用、保留等。lm命令将显示所有DLL和EXE的加载地址及其范围。这个vadump命令将显示进程和页面保护使用的所有虚拟内存。页面保护是一个很好的提示。例如在下面(部分)!从64位calc.exe进程中,您将看到第一个区域只是一个受保护的虚拟内存范围,不允许访问。(除其他外,这使您无法在地址0处分配内存。)MEM_COMMIT意味着内存由RAM或分页文件支持。PAGE_READWRITE可能是堆内存,或加载模块的数据段。PAGE_READEXECUTE通常是加载的代码,它将显示在lm生成的列表中。MEM_RESERVE意味着一种称为VirtualAlloc的东西来保留一个内存区域,但它不是由虚拟内存管理器映射的,等等

    0:004> !vadump
    BaseAddress:       0000000000000000
    RegionSize:        0000000000010000
    State:             00010000  MEM_FREE
    Protect:           00000001  PAGE_NOACCESS
    
    BaseAddress:       0000000000010000
    RegionSize:        0000000000010000
    State:             00001000  MEM_COMMIT
    Protect:           00000004  PAGE_READWRITE
    Type:              00040000  MEM_MAPPED
    
    BaseAddress:       0000000000020000
    RegionSize:        0000000000003000
    State:             00001000  MEM_COMMIT
    Protect:           00000002  PAGE_READONLY
    Type:              00040000  MEM_MAPPED
    
    我希望这有助于解释问题。Windbg是一个很好的工具,有许多扩展可以帮助您找到内存的使用位置


    如果你真的关心堆,看看!堆。

    首先,感谢您使用我的工具。我希望您觉得它很有用,可以随时提交功能请求或贡献

    通常,地址空间中固定点上的薄片是由链接DLL在其首选地址加载引起的。在地址空间中负载较高的往往是Microsoft操作系统DLL。如果这些都可以加载,操作系统的效率会更高