【问题标题】:Cleaning dynamic memory of linked objects清理链接对象的动态内存
【发布时间】:2013-03-18 12:59:59
【问题描述】:

我需要清理链接对象的动态内存。我正在研究优化问题的分支定界算法。我有一个名为“节点”的类,它保存部分解决方案的数据。我使用“新”功能创建节点。所有创建的节点都相互链接,形成一个链,就像我创建了一个手动列表一样。每个节点都知道紧随其后的最佳节点的物理地址。这个链条是动态的。使用现有节点,我生成新节点并将它们相应地链接到链,直到找到最佳解决方案。对于一些问题,当节点数量约为 30 亿(30-40 GB)时,我找到了最佳解决方案。我将我的代码设置为通过解决下一个问题,当它完成解决一个问题时(我通过在处理过程中的多个文件流来做到这一点)。我需要在通过解决另一个问题之前释放内存。当我找到最佳且不再需要节点链时,我尝试使用“删除”功能。坏事是删除 30 亿个相互链接的节点对象需要几个小时。我正在终止程序,从目录中删除已解决的文件,等待 Windows 释放 RAM,然后再次重新启动以继续我的工作。 有没有办法释放内存,同时传递给另一个问题来解决,比如终止进程所做的清理操作,还是我应该改变节点链的结构?

【问题讨论】:

    标签: c++ linked-list dynamic-memory-allocation


    【解决方案1】:

    听起来像是一个定制新的工作,它从你可以解除分配的池中分配。

    class Node
    {
        void* operator new(size_t bytes);
        void delete(void* ptr) {}
        ...
    };
    

    现在你的 operator 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; 即可释放所有内存。反正是这样的。有一些细节要补充。

    【讨论】:

    • 不应该是void* Node::operator new(size_t bytes)吗?您还忘记在删除之前添加运算符。
    【解决方案2】:

    如果你有 30 亿个对象,你需要释放 30 亿个对象。除非你作弊。

    正如您已经正确指出的那样,一种作弊方式是终止进程。当然,这排除了之后做其他事情的可能性。

    另一种方法是重载operator new 以使用块分配器,而operator delete 什么也不做(或一起忘记operator delete)。块分配器将分配一个巨大的块(或者根据需要分配几个块,这些块可能在链表中),从中提取您分配的对象。这可以以相对简单的方式实现(从数组中返回一个元素,并增加索引)。

    然后,当您处理完 30 亿个对象后,在块分配器中调用一个函数,该函数一次简单地丢弃整个块(释放它们)。分配器不知道这 30 亿个对象,也不关心。它所做的只是一次(或者可能是 3-4 次)大型解除分配。

    【讨论】:

      【解决方案3】:

      使用析构函数释放由构造函数分配的资源,或由增变器分配的额外资源。

      【讨论】:

      • 如果他使用delete,会自动调用析构函数。他的观点是,这个过程对他的申请来说太长了。
      猜你喜欢
      • 2020-06-05
      • 2014-10-26
      • 1970-01-01
      • 2014-10-19
      • 2022-01-16
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 2020-03-27
      相关资源
      最近更新 更多