我需要清理链接对象的动态内存。我正在学习分支。一类优化问题的定界算法。我有一个类叫做"node"它保存了部分解的数据。我使用"new"函数创建节点。所有创建的节点都相互链接,形成一个链,就像我创建一个曼纽尔列表一样。每个节点都知道紧随其后的最佳节点的物理地址。这个链是动态的。使用现有的节点,我生成新的节点,并将它们链接到相应的链上,直到我找到最优解决方案。对于一些问题,当节点数量大约为30亿(30-40 GB)时,我找到了最佳解决方案。我将我的代码设置为在完成解决一个问题时传递以解决下一个问题(我在过程中通过多个文件流来实现这一点)。我需要在传递之前释放内存以解决另一个问题。当我找到最优时,当我不再需要节点链时,我试图使用"删除"函数。糟糕的是,删除30亿个彼此链接的节点对象需要花费数小时。我正在终止程序,从目录中删除解决的文件,等待窗口释放RAM,然后重新启动它以继续我的工作。是否有一种方法可以释放内存,同时传递给另一个问题来解决,如终止进程所做的清理操作,或者我应该改变节点链的结构?
听起来像是一个定制的new任务,它从一个可以释放的池中分配资源。
class Node
{
void* operator new(size_t bytes);
void delete(void* ptr) {}
...
};
现在你的操作符new可以做这个
char* big_block = new char[100000];
char* free_ptr = big_block;
void* Node::operator new(size_t bytes)
{
char* ptr = free_ptr;
free_ptr += bytes;
return ptr;
}
当你完成后,你可以调用delete[] big_block;
,所有的内存都被释放了。差不多就是这样。还有一些细节需要添加
如果您有30亿个对象,则需要释放30亿个对象。除非你作弊。
作弊的一种方式是终止进程,正如你已经正确指出的那样。当然,这就排除了之后做其他事情的可能性。另一种方法是重载operator new
以使用块分配器,而operator delete
不做任何事情(或者完全忘记operator delete
)。块分配器将分配一个巨大的块(或者根据需要分配几个块,这些块可以在链表中),从中绘制您分配的对象。这可以用一种相对简单的方式实现(从数组中返回一个元素,并增加索引)。
然后,当你用完30亿个对象后,在块分配器中调用一个函数,一次简单地扔掉整个块(释放它们)。分配器不知道30亿个对象,也不关心。它所做的只是一次(或3-4次)大的释放。
使用析构函数释放由构造函数分配的资源,或由变异函数分配的额外资源。