我一直在使用malloc()
开发我的程序来分配内存。但是,我的调查让我觉得我正面临内存碎片问题。
我的程序需要5个内存分配,每个分配大约70 MB。当我使用4个线程运行我的程序时,我需要5x4内存分配,每个~70 MB(我不能使用更少的内存)。最后,我希望能够使用i7的8核,即5x8内存分配。
如果我执行5x2 malloc(),程序可以运行。不适用于5x3 malloc()s。
我一直在阅读std::vector
和std::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位应用程序。因此,可能不是一个碎片问题。
答案 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::vector
或std::deque
无法解决您的问题,如果它是碎片或过度分配(最有可能)。他们都会在他们的实现中使用new/malloc
来分配内存,所以如果你已经知道你的分配范围,你也可以预先请求全部金额。
还有其他任何可供探索的解决方案或std :: deque是我唯一的解决方案吗?
deque
不是解决方案答案 1 :(得分:0)
这取决于你有多少RAM。你需要5 * 70MB * 8 = 2800MB。有些情况:
std::list
会很糟糕,因为它需要一个指向每个元素的指针。因此,如果你的向量包含一些大项目,切换到列表会因为这些指针而给你带来一点开销,但是如果它们持有很多小值,那么列表会强迫你浪费大量空间存储指针。从这个意义上说,deque应该是你需要的,因为在内部它通常被实现为一组数组,所以你不需要指向每个元素的指针。总结:是的,deque是你正在寻找的。它需要比向量更多的内存,但只需要一点点,并且内存不会是连续的,所以你不应该有更多的RAM碎片问题。