我一直在使用malloc()
来开发我的程序来分配内存。 但是,我的调查让我觉得我面临着一个内存碎片问题。
我的程序需要5个内存分配,每个〜70 MB。 当我使用4个线程运行我的程序时,我需要每个〜70 MB的5×4内存分配(并且我不能使用更less的内存)。 最后,我想能够使用我的i7的8个内核,这是5×8内存分配。
如果我做5×2 malloc(),程序工作。 不适用于5×3 malloc()s。
我一直在阅读关于std::vector
和std::deque
。 我相信, std::deque
是我解决这个问题的方法,因为std::vector
会把连续内存的一大块分配给malloc()
。
还有其他的解决scheme来探索或std::deque
是我唯一的解决scheme吗?
操作系统:Windows 8.1(x64)
RAM:8 GB(5 GB可用空间)
我通过检查errno == ENOMEM
检测malloc()
错误
注: ERROR_MEM_ALLOC_FAILED
是内存分配失败时所生成的错误之一。
具有4个线程(即5×4 malloc()
s)的程序的debugging跟踪:
Start Thread 01 (+53.40576 MB) Total allocated 53.4/4095 total MB (+53.40576 MB) Total allocated 106.8/4095 total MB (+0.00008 MB) Total allocated 106.8/4095 total MB (+0.00008 MB) Total allocated 106.8/4095 total MB Tried to allocate 267 MB ERROR_MEM_ALLOC_FAILED Thread 02 (+53.40576 MB) Total allocated 160.2/4095 total MB (+53.40576 MB) Total allocated 213.6/4095 total MB (+0.00008 MB) Total allocated 213.6/4095 total MB (+0.00008 MB) Total allocated 213.6/4095 total MB Tried to allocate 267 MB ERROR_MEM_ALLOC_FAILED Thread 03 (+53.40576 MB) Total allocated 267.0/4095 total MB Tried to allocate 53 MB ERROR_MEM_ALLOC_FAILED Thread 04 Tried to allocate 53 MB ERROR_MEM_ALLOC_FAILED End of program
我试图运行同样的事情,但改变了内存分配的顺序,但没有分配内存。
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
解决scheme是将应用程序编译为64位应用程序。 因此,可能这不是一个分裂问题。
你为什么认为这是一个内存碎片问题? 碎片化通常是由于分配和删除大量不同大小的块而导致的,导致在可用或不可用大小的分配之间存在空闲的可用内存。 这听起来不像你描述的内存访问模式。
而且,这个数量的内存不是今天的标准,尽管它取决于你的硬件和操作系统。 你的机器有多少物理内存? 你在运行什么操作系统? 它是作为一个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
不是解决方案 这取决于你有多少RAM。 你需要5 * 70MB * 8 = 2800MB。 有一些情况:
std::list
将是非常糟糕的,因为它需要一个指向每个元素的指针。 所以,如果你的向量只包含一些大的项目,那么切换到列表会给你一些额外的开销,但是如果它们拥有很多小的值,这个列表将会迫使你浪费大量的空间来存储指针。 从这个意义上讲,deque应该是你所需要的,因为它在内部通常是作为一组数组来实现的,所以你不需要指向每个元素的指针。 总而言之:是的,你需要的是一个双簧管。 这将需要比矢量更多的内存,但只有一点,而且内存不必是连续的,所以你不应该有更多的内存碎片问题。