大量数据在C ++中碎片化(Windows)

我一直在使用malloc()来开发我的程序来分配内存。 但是,我的调查让我觉得我面临着一个内存碎片问题。

我的程序需要5个内存分配,每个〜70 MB。 当我使用4个线程运行我的程序时,我需要每个〜70 MB的5×4内存分配(并且我不能使用更less的内存)。 最后,我想能够使用我的i7的8个内核,这是5×8内存分配。

如果我做5×2 malloc(),程序工作。 不适用于5×3 malloc()s。

我一直在阅读关于std::vectorstd::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::vectorstd::deque不一定能解决你的问题,如果它是碎片或者重新分配(最有可能的)。 他们都会在实现中使用new/malloc来分配内存,所以如果你已经知道你的分配的范围,那么你也可以像你一样要求全部的数量。

还有其他的解决方案来探索或std :: deque是我唯一的解决方案吗?

  1. deque不是解决方案
  2. 分析你的内存需求,访问模式和减少使用
  3. 如果您的使用率远远低于2GB,请切换到64位操作系统

这取决于你有多少RAM。 你需要5 * 70MB * 8 = 2800MB。 有一些情况:

  • 如果你有更多的东西,即使在连续的块里,也不应该是一个问题。 我想你没有那么多
  • 另一方面,如果你没有那么多的内存,没有容器可以满足你的需要,除了增加内存或者修改你的程序来使用更少的内核之外,没有什么可以做的。
  • 在中间情况下,也就是说,你的记忆不会少于这个数字,但是也不能太多,切换到另一个容器可能会工作,但是仍然存在问题:记住一个矢量是非常节省空间的,因为它是连续的; 任何类型的链表都需要存储指向下一个元素的指针,而这些指针可能占用很大的空间,所以最终可能需要超过2800MB,尽管不是连续的块。 从这个角度来看, std::list将是非常糟糕的,因为它需要一个指向每个元素的指针。 所以,如果你的向量只包含一些大的项目,那么切换到列表会给你一些额外的开销,但是如果它们拥有很多小的值,这个列表将会迫使你浪费大量的空间来存储指针。 从这个意义上讲,deque应该是你所需要的,因为它在内部通常是作为一组数组来实现的,所以你不需要指向每个元素的指针。

总而言之:是的,你需要的是一个双簧管。 这将需要比矢量更多的内存,但只有一点,而且内存不必是连续的,所以你不应该有更多的内存碎片问题。