C中的问题使用记忆

0 c linux malloc free cc

请帮助:)操作系统:Linux

在"sleep(1000);"中,此时"top(显示Linux任务)"给我写了7.7%MEM使用.valgrind:没发现内存泄漏.

我明白了,写得正确,所有malloc结果都是NULL.但为什么在这个时候"睡觉"我的程序不会减少记忆?遗失了什么?

抱歉我的英文不好,谢谢


~ # tmp_soft
For : Is it free??  no
Is it free??  yes
For 0 
For : Is it free??  no
Is it free??  yes
For 1 
END : Is it free??  yes
END 

~ #top
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                
23060 root      20   0  155m 153m  448 S    0  7.7   0:01.07 tmp_soft    
Run Code Online (Sandbox Code Playgroud)

完整来源:tmp_soft.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

struct cache_db_s
{
 int       table_update;
 struct    cache_db_s * p_next;
};

void free_cache_db (struct cache_db_s ** cache_db)
{
 struct cache_db_s * cache_db_t;
 while (*cache_db != NULL)
 {
  cache_db_t = *cache_db;
  *cache_db = (*cache_db)->p_next;
  free(cache_db_t);
  cache_db_t = NULL;
 }
 printf("Is it free??  %s\n",*cache_db==NULL?"yes":"no");
}

void make_cache_db (struct cache_db_s ** cache_db)
{
 struct cache_db_s * cache_db_t = NULL;
 int n = 10000000;

 for (int i=0; i = n; i++)
 {
  if ((cache_db_t=malloc(sizeof(struct cache_db_s)))==NULL) {
   printf("Error : malloc 1 -> cache_db_s (no free memory) \n");
   break;
  }
  memset(cache_db_t, 0, sizeof(struct cache_db_s));

  cache_db_t->table_update = 1; // tmp 

  cache_db_t->p_next = *cache_db;
  *cache_db = cache_db_t;
  cache_db_t = NULL;
 }
}

int main(int argc, char **argv)
{
 struct cache_db_s * cache_db = NULL;

 for (int ii=0; ii  2; ii++) {
  make_cache_db(&cache_db);
  printf("For : Is it free??  %s\n",cache_db==NULL?"yes":"no");
  free_cache_db(&cache_db);
  printf("For %d \n", ii);
 }

 printf("END : Is it free??  %s\n",cache_db==NULL?"yes":"no");
 printf("END \n");
 sleep(1000);
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dig*_*oss 11

出于好的理由,几乎没有内存分配器将块返回给OS


内存只能以页面为单位从程序中删除,甚至不太可能被观察到.

如果需要,calloc(3)和malloc(3)确实与内核交互以获取内存.但是很少很少的free(3)实现将内存返回到内核1,它们只是将它添加到一个空闲列表中,calloc()和malloc()稍后会参考,以便重用已发布的块.这种设计方法有充分的理由.

即使free()想要将内存返回给系统,它也需要至少一个连续的内存页才能让内核真正保护该区域,因此释放一个小块只会导致保护更改,如果它是页面中的最后一个小块.

运作理论

因此malloc(3)在需要时从内核获取内存,最终以离散页面倍数为单位.这些页面按程序要求进行划分或合并.Malloc和免费合作维护目录.它们在可能的情况下合并相邻的自由块,以便能够提供大块.该目录可能涉及或可能不涉及使用释放块中的存储器来形成链表.(替代方案是更多共享内存和分页友好,它涉及专门为目录分配内存.)即使特殊和可选的调试代码被编译成,Malloc和free几乎没有能力强制访问单个块.该程序.


1.很少有free()实现尝试将内存返回系统的事实根本不是由于实现者的松弛.

与内核交互比简单地执行库代码慢得多,而且好处很小.大多数程序具有稳态或增加的内存占用,因此分析堆寻找可返回内存所花费的时间将完全被浪费.其他原因包括内部碎片使页面对齐的块不太可能存在,并且返回块可能会将块分块到任何一侧.最后,几个返回大量内存的程序可能会绕过malloc()并简单地分配和释放页面.