【问题标题】:Memory consumption after new then delete新建然后删除后的内存消耗
【发布时间】:2018-09-14 00:34:28
【问题描述】:

我创建了一个示例应用程序,如下所示。我需要创建 1024*1024 结构。在调用 new 运算符之前,我的应用程序正在消耗一些内存(比如 0.3mb)。调用新运算符后,内存会增加(比如 175mb)。调用delete 运算符后,内存减少(比如15mb)。因此,最终在内存中存在差异。我从任务管理器中观察了所有这些内存细节。我很困惑是否应该将其视为内存泄漏,还是该内存会慢慢释放?如果没有,我怎样才能释放剩余的内存?

struct testSt
{
    bool        check;
    std::string testString; 

};

int main()
{
    testSt *testObj = new testSt[1024 * 1024];
    delete[] testObj;

    return 0;
}

【问题讨论】:

    标签: c++ windows memory memory-leaks


    【解决方案1】:

    您的应用程序中绝对没有内存泄漏。分配之前和之后的数字似乎不匹配的原因是任务管理器工具对于检测 C++ 程序中的内存泄漏来说是粗略的。它不仅记录代码的内存使用情况,还记录执行代码的进程的所有内存使用情况,包括支持代码操作的标准 C++ 库使用的任何内存。

    使用内存分析器(例如 valgrind)来测试您的代码是否存在内存泄漏。

    此外,考虑从原始指针切换到创建容器。到目前为止,减少内存泄漏可能性的最佳方法是使用标准 C++ 库中的容器来自动化内存管理。在您的情况下,定义一个向量

    std::vector<testSt> testObj(1024*1024);
    

    会让您完全避免分配和释放。

    【讨论】:

    • 另外值得注意的是,delete 并不一定会将内存归还给操作系统,而是保留它以供以后分配(需要来源,但这是我的经验)。
    • @OMGtechy 完全正确。我试图在第一段的最后一句中用不太具体的术语将其暗示为“支持代码操作的标准 C++ 库使用的内存”。通常,内存分配器往往不会放弃所有内存,或者至少不会立即放弃所有内存。它们的运作假设是,如果您之前请求过内存,您很可能会再次请求内存,因此它们会在手边保留一个“私人存储”。
    • 虽然这在小分配中很常见,但许多分配器倾向于立即交还大分配。并且一百万个testSt 对象很可能被视为用于此目的的大量分配。
    【解决方案2】:

    发布的代码中没有内存泄漏。任务管理器报告的内存使用情况没有恢复到原来的状态的原因是进程的运行时保留了一些分配的页面以供以后重用,因此它(希望)不必打扰操作系统以获得更多 RAM下次它想分配一个对象。这是一个正常的优化,没什么好担心的。泄漏的真正测试是在循环中运行您的代码进行多次迭代;如果在该测试期间您看到您的进程的内存使用量无限制地增加,则表明存在内存泄漏。另一方面,如果它趋于平稳然后保持不变,则表明不存在。

    【讨论】:

      【解决方案3】:

      您的代码是正确的,该数组将被删除。 您可以使用以下方法对此进行测试:

      struct testSt
      {
          bool        check;
          std::string testString;
      
          ~testSt()
          {
              std::cout << "Destroyed!" << std::endl;
          }
      };
      

      您是从调试器运行的吗?额外的内存可能由 IDE 持有。

      【讨论】:

      • 我没有看到 OP 计算了超过一百万行的“Destroyed!”以确保没有错过;)
      猜你喜欢
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2010-10-30
      相关资源
      最近更新 更多