C++ C+中的碎片+;大数据块(Windows)
我一直在使用C++ C+中的碎片+;大数据块(Windows),c++,windows,memory-management,C++,Windows,Memory Management,我一直在使用malloc()分配内存来开发我的程序。然而,我的调查让我认为我面临着内存碎片问题 我的程序需要5个内存分配,每个大约70 MB。当我使用4个线程运行我的程序时,我需要5x4个内存分配,每个大约70 MB(我不能使用更少的内存)。最后,我希望能够使用i7的8个核心,即5x8内存分配 如果我执行5x2 malloc()s,程序就会工作。不适用于5x3 malloc()s 我一直在读关于std::vector和std::deque。我相信std::deque是我解决这个问题的方法,因为s
malloc()
分配内存来开发我的程序。然而,我的调查让我认为我面临着内存碎片问题
我的程序需要5个内存分配,每个大约70 MB。当我使用4个线程运行我的程序时,我需要5x4个内存分配,每个大约70 MB(我不能使用更少的内存)。最后,我希望能够使用i7的8个核心,即5x8内存分配
如果我执行5x2 malloc()s,程序就会工作。不适用于5x3 malloc()s
我一直在读关于std::vector
和std::deque
。我相信std::deque
是我解决这个问题的方法,因为std::vector
像malloc()
还有其他的解决方案需要探索吗?或者,std::deque
是我唯一的解决方案
编辑
操作系统:Windows 8.1(x64)
RAM:8GB(5GB的可用空间)
我通过检查errno==ENOMEM
注意:ERROR\u MEM\u ALLOC\u FAILED
是我在内存分配失败时生成的错误之一
具有4个线程(即5x4malloc()
s)的程序的调试跟踪:
我试图运行相同的东西,但改变了内存分配的顺序,但没有分配内存
Start
Thread 01
Tried to allocate 267 MB
ERROR_MEM_ALLOC_FAILED
Thread 02
Tried to allocate 267 MB
ERROR_MEM_ALLOC_FAILED
Thread 03
Tried to allocate 267 MB
ERROR_MEM_ALLOC_FAILED
Thread 04
Tried to allocate 267 MB
ERROR_MEM_ALLOC_FAILED
End of program
解决方案
解决方案是将应用程序编译为64位应用程序。因此,这可能不是一个碎片问题。这取决于您有多少RAM。您需要5*70MB*8=2800MB。有一些情况:
- 如果您有比这更多的内容,那么即使在连续的块中找到它也不成问题。我想你没有那么多
- 另一方面,如果您没有那么多内存,那么就没有适合您需要的容器,而且除了添加RAM或修改程序以使用更少的内核之外,您真的无能为力
- 在中间的情况下,也就是说,您的内存不少于此值,但也不超过此值,切换到另一个容器可能会起作用,但仍然存在问题:请记住,向量非常节省空间,因为它是连续的;任何类型的链表都需要存储指向下一个元素的指针,这些指针可能占用大量空间,因此最终可能需要2800MB以上的内存,尽管不是在连续的块中。从这个角度来看,
std::list
,会很糟糕,因为它需要一个指向每个元素的指针。因此,如果你的向量包含一些大的项目,切换到列表会给你一些开销,因为指针太少,但是如果它们包含很多小的值,列表会迫使你浪费很多空间来存储指针。从这个意义上讲,deque应该是您所需要的,因为在内部它通常是作为一组数组实现的,所以您不需要指向每个元素的指针
总结:是的,deque是你想要的。它将需要比向量更多的内存,但只需要一点点,而且内存不必是连续的,因此您不应该再有任何RAM碎片问题。为什么您认为这是内存碎片问题?碎片通常是由分配和删除大量大小不同的块引起的,这会导致分配之间的可用内存孔大小不可用或无用。这听起来一点也不像你描述的内存访问模式
此外,按照今天的标准,这个内存量并不大,尽管它取决于您的硬件和操作系统。您的机器有多少物理内存?你在运行什么操作系统?它是作为32位还是64位应用程序构建的?您如何知道malloc
失败-是否返回null
?你试过内存分析吗
Heap usage: 8 threads * 5 blocks * 70MB per block = 2800MB total
在Windows上,对于32位程序,堆分配的默认每个进程限制为2GB,因此很可能达到此限制。也许最好的解决方案是在64位模式下开发应用程序,然后您可以分配大量(虚拟)RAM
我一直在读关于std::vector和std::deque的文章。我相信std::deque是我解决这个问题的方法,因为std::vector像malloc()一样分配一大块连续内存
不,使用std::vector
或std::deque
不一定能解决您的问题,如果是碎片化或过度分配(最有可能)。它们在实现中都将使用new/malloc
来分配内存,因此,如果您已经知道分配的界限,那么您可以像现在这样提前请求全额内存
还有其他解决方案需要探索吗?或者std::deque是我唯一的解决方案
deque
不是解决方案
分析内存需求、访问模式并减少使用
如果您无法获得低于2GB的使用率,请切换到64位操作系统
当您的程序无法运行时会发生什么情况(5x3 malloc's)?您确定是malloc失败了吗?如果您还可以详细说明通过分配如此巨大的阵列想要实现什么,那就太好了。因为,从不同的角度来看,您可能不需要这样的分配。@Tryum是,在每次malloc之后,我检查errno=ENOMEM@sameerkn我执行数学运算,所以我需要这些分配。我有一堆700万个样本记录道,其中包含必须关联的相关数据。我不认为我做错了。我认为这有点离题。我已经回答了一些关于我主要问题的问题。目前我不知道我的应用程序是32位还是64位。我还没有尝试过内存分析,我将寻找一些与此相关的信息。我可以将我的应用程序编译为64位应用程序。现在它正在工作。谢谢。@McD0n3ld很好,很高兴听到。在虚拟内存系统中,amou
Heap usage: 8 threads * 5 blocks * 70MB per block = 2800MB total