C ++中的碎片与大块数据(Windows)

时间:2016-06-16 09:23:08

标签: c++ windows memory-management

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

我的程序需要5个内存分配,每个分配大约70 MB。当我使用4个线程运行我的程序时,我需要5x4内存分配,每个~70 MB(我不能使用更少的内存)。最后,我希望能够使用i7的8核,即5x8内存分配。

如果我执行5x2 malloc(),程序可以运行。不适用于5x3 malloc()s。

我一直在阅读std::vectorstd::deque。我相信std::deque是我解决此问题的方法,因为std::vector会为malloc()分配一大块连续内存。

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

修改

操作系统:Windows 8.1(x64)

RAM:8 GB(5 GB可用空间)

我通过检查malloc()

检测到errno == ENOMEM错误

注意:ERROR_MEM_ALLOC_FAILED是我在内存分配失败时生成的错误之一。

具有4个线程(即5x4 malloc() s)的程序的调试跟踪:

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

解决方案是将应用程序编译为64位应用程序。因此,可能不是一个碎片问题。

2 个答案:

答案 0 :(得分:2)

为什么你认为它是内存碎片问题?碎片通常是由分配和删除大量不同大小的块引起的,导致在不可用或有用大小的分配之间存在可用内存漏洞。它完全不像你描述的内存访问模式。

此外,根据今天的标准,这个内存量并不大,但这取决于您的硬件和操作系统。你的机器有多少物理内存?你在运行什么操作系统?它是构建为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位操作系统

答案 1 :(得分:0)

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

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

总结:是的,deque是你正在寻找的。它需要比向量更多的内存,但只需要一点点,并且内存不会是连续的,所以你不应该有更多的RAM碎片问题。