我怎样才能保证在释放内存时,操作系统会回收内存以供其使用?

Lyi*_*Sky 2 c linux memory memory-management

我注意到这个程序:

#include <stdio.h>

int main() {
  const size_t alloc_size = 1*1024*1024;
  for (size_t i = 0; i < 3; i++) {
    printf("1\n");
    usleep(1000*1000);
    void *p[3];
    for (size_t j = 3; j--; )
      memset(p[j] = malloc(alloc_size),0,alloc_size); // memset for de-virtualize the memory
    usleep(1000*1000);
    printf("2\n");
    free(p[i]);
    p[i] = NULL;
    usleep(1000*1000*4);
    printf("3\n");
    for (size_t j = 3; j--; )
      free(p[j]);
  }
}
Run Code Online (Sandbox Code Playgroud)

它分配3个存储器,3次,每次释放不同的存储器,根据存储器释放存储器watch free -m,这意味着free无论存储器在程序地址空间内的位置如何,OS都会为每个存储器回收存储器.我可以以某种方式得到这种效果的保证吗?或者是否已经有类似的东西(比如>64KB分配规则)?

chq*_*lie 5

简短的回答是:通常,您无法保证操作系统将回收释放的内存,但可能有特定于操作系统的方法来执行此操作或更好的方法来确保此类行为.

答案很长:

  • 您的代码具有未定义的行为:在超出数组末尾的访问free(p[i]);之后还有一个额外的行为.printf("2\n");p

  • 您为库进行单独的系统调用(例如mmap在Linux系统中)分配大块(1 MB),并将free这些块释放到OS,从而观察到行为.

  • 各种操作系统可能会针对系​​统特定阈值(通常为128KB)实现此类行为,但C标准对此提供了保证,因此依赖此类行为是系统特定的.

  • 阅读系统上的手册页,malloc()了解是否可以控制此行为.例如,Linux上的C库使用环境变量MMAP_THRESHOLD来覆盖此阈值的默认设置.

  • 如果编程为Posix目标,则可能需要mmap()直接使用而不是malloc保证在释放后将内存返回给系统munmap().请注意,返回的块mmap()将在第一次访问之前初始化为所有位零,因此您可以避免这种显式初始化以利用按需分页,执行显式初始化以确保映射内存以尝试并最小化延迟以后的行动.

  • 好吧,取决于你对"帮助你"的意思:你还没有说出你的*问题*是什么,坦率地说,所有这些都是[XY问题](http://xyproblem.info)**的极度许多**.因此,请编辑您的问题并解释为什么您认为答案与您正在解决的问题相关,以及该问题实际上是什么. (2认同)