操作系统资源回收问题——delete或者free释放的内存会立即回收到操作系统吗?

delete或者free释放的内存会立即回收到操作系统吗?

答案是大概率不会。

这是我在开发过程中遇到的一个问题:在机器人运行过程中,有时候需要从一个大地图切换到更小的地图。这个需求在代码上的实现是析构掉运行大地图时保存的数据,重新构造对象加载小地图的数据。一开始因为不了解这个问题,期望的是切换小地图后该进程占用的内存资源会有所下降,但是通过$top查看资源使用情况却发现没有下降,甚至稍微有点增加。

这个现象我们最直接的反应就是代码中可能存在内存泄漏,对象析构后可能某些使用new分配资源没有释放。为此对代码进行了检查,并通过在那些主要申请资源的对象的析构函数中打印输出来确认它们析构的执行。一番折腾还是发现不了问题所在。在确认各对象都的确被析构后,我们讨论,这个问题是不是由系统造成的,也就是虽然资源被释放了,但是没有被系统回收。于是我们开始Google这个问题,找到如下相关结果(可能需要上外网,上不了可以看截图):

  1. https://stackoverflow.com/questions/52417318/why-does-the-free-function-not-return-memory-to-the-operating-system/52417370

  2. https://lemire.me/blog/2020/03/03/calling-free-or-delete/

  3. http://www.cplusplus-soup.com/2010/01/freedelete-not-returning-memory-to-os.html?m=1

上面这些回答或者博客总结起来就是:

  • 内存(memory)是在堆(heap)上分配的。当进程 (process)请求内存时是向堆(堆管理器)请求内存,而堆又向操作系统(OS)申请内存。由于这种操作代价比较大,操作系统一般是分配给一块(chunk)内存给堆,以减少内存操作(还是说系统调用)次数。因此进程调用delete或者free释放资源后,这些资源归还给了这个程序所申请到的堆,而堆不一定会将资源归还给操作系统(取决于操作系统类型、内存块的大小等因素)。这部分没有归还的资源在当前进程再次(使用new或malloc)申请内存时可以被重用,因此这样可以避免频繁与操作系统进行“内存交互”。这些释放的资源在进程结束后随着整个堆一起归还给OS。当然,如果想要强制回收资源也是有路子的,如博客中所说可以尝试malloc_trim。

以上是我对“操作系统资源回收”问题的研究和总结,欢迎交流讨论。
如果错误或不当之处,欢迎指教。
如果对你有帮助,可以给个赞表示鼓励:D。

posted @ 2021-11-06 11:11  意大利泡面  阅读(1088)  评论(0编辑  收藏  举报