考虑一个基于两个步骤的MPI应用程序,我们将其称为load和globalReduce。为了简单起见,软件被描述为如此,但是还有很多事情正在进行,因此它并不是纯粹的Map/Reduce问题。

在加载步骤中,每个给定节点中的所有等级都排队,因此只有一个等级可以完全访问该节点的所有内存。这种设计的原因是由于在加载阶段读取了一组大型IO块,并且都需要将它们全部加载到内存中才能进行本地还原。我们将这种局部归约的结果称为命名变量myRankVector。获得myRankVector变量后,将释放IO块。变量myRankVector本身使用的内存很少,因此,在创建节点期间,节点可以使用所有内存,完成后,等级仅需要使用2-3 GB的空间即可保存myRankVector。

在节点的globalReduce阶段,预计节点中的所有等级均已加载了相应的globalReduce。

所以这是我的问题,尽管我确保绝对没有任何内存泄漏(我使用共享指针编程,我使用Valgrind进行了两次检查,等等),但是我很肯定即使释放了所有析构函数,堆仍然保持扩展状态IO块。当队列中的下一个队列开始工作时,它就像上一个队列一样开始请求大量内存,并且该程序当然会杀死Linux,并产生“内存不足:杀死进程xxx(xxxxxxxx)得分xxxx或牺牲 child ”。很明显为什么是这种情况,队列中的第二个等级要使用所有内存,而第一个等级仍然保留着大堆。

因此,在设置此问题的上下文之后:是否有一种方法可以手动减小C++中的堆大小以真正释放未使用的内存?

谢谢。

最佳答案

堆是在Linux上使用mmap来实现的,您将需要使用自己的堆,可以完全对其进行处置和munmap。
munmap将释放所需的空间。

查看boost : pool中的代码以获取实现,该实现将允许您独立管理基础堆。

以我的经验,使用自定义分配器管理std容器非常困难,因为它们是类派生的,而不是实例派生的。

10-07 22:27