当vector push_back string时,Mac上不释放内存



代码如下,发现当向量push_back字符串在Mac演示应用程序上时,内存没有被释放。我认为堆栈变量将在超出函数范围时被释放,我错了吗?谢谢你的建议。

in model.h:

#pragma once
namespace NS {
    const uint8_t kModel[8779041] = {4,0,188,250,....};
}

in ViewController.mm:

- (void)start {
    std::vector<std::string> params = {};
    std::string strModel(reinterpret_cast<const char *>(NS::kModel), sizeof(NS:kModel));
    params.push_back(strModel);
}

这个问题的答案取决于你对"免费"的理解。内存。您正在观察的行为可以简单地复制为几行代码:

void myFunc() {
    const auto *ptr = new uint8_t[8779041]{};
    delete[] ptr;
}

让我们运行这个函数,看看内存消耗图是如何变化的:

int main() {
    myFunc(); // 1 MB
    std::cout << "Check point" << std::endl; // 9.4 MB
    return 0;
}

如果您将一个断点放在myFunc()调用行,另一个断点放在"Check point"控制台输出行,您将看到进程的内存消耗如何跳跃大约8 MB(对于我的系统和机器配置Xcode显示从1 MB突然跳到9.4 MB)。但是,等等,在函数结束后,它不应该是1 MB,因为分配的内存在函数结束时被释放?嗯,不完全是……系统不会立即重新获得这些内存,因为一开始就不是那么便宜的操作,如果您的进程在1个CPU周期后请求相同数量的内存,这将是相当冗余的工作。因此,系统通常不会费心缩减一个进程专用的内存,直到另一个进程需要它,直到它耗尽可用资源(它也可以是某种固定计时器,但总的来说,我认为这是实现定义的)。内存没有被释放的另一个常见原因是,您经常通过调试模式观察它,在调试模式中,内存仍然专用于进程,以跟踪一些棘手的场景(如NSZombie对象,其地址需要保持对进程的可访问性,以便报告释放后使用的情况)。

这里最重要的是,在内部,进程可以区分"deleted"one_answers";occupied"内存页,因此它可以重新占用已经删除的内存。因此,无论调用同一个函数多少次,专用于该进程的内存都保持不变:

int main() {
    myFunc(); // 1 MB
    std::cout << "Check point" << std::endl; // 9.4 MB
    for (int i = 0; i < 10000; ++i) {
        myFunc();
    }
    std::cout << "Another point" << std::endl; // 9.4 MB
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新