请帮助:)操作系统: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
内存只能以页面为单位从程序中删除,甚至不太可能被观察到.
如果需要,calloc(3)和malloc(3)确实与内核交互以获取内存.但是很少很少的free(3)实现将内存返回到内核1,它们只是将它添加到一个空闲列表中,calloc()和malloc()稍后会参考,以便重用已发布的块.这种设计方法有充分的理由.
即使free()想要将内存返回给系统,它也需要至少一个连续的内存页才能让内核真正保护该区域,因此释放一个小块只会导致保护更改,如果它是页面中的最后一个小块.
因此malloc(3)在需要时从内核获取内存,最终以离散页面倍数为单位.这些页面按程序要求进行划分或合并.Malloc和免费合作维护目录.它们在可能的情况下合并相邻的自由块,以便能够提供大块.该目录可能涉及或可能不涉及使用释放块中的存储器来形成链表.(替代方案是更多共享内存和分页友好,它涉及专门为目录分配内存.)即使特殊和可选的调试代码被编译成,Malloc和free几乎没有能力强制访问单个块.该程序.
1.很少有free()实现尝试将内存返回系统的事实根本不是由于实现者的松弛.
与内核交互比简单地执行库代码慢得多,而且好处很小.大多数程序具有稳态或增加的内存占用,因此分析堆寻找可返回内存所花费的时间将完全被浪费.其他原因包括内部碎片使页面对齐的块不太可能存在,并且返回块可能会将块分块到任何一侧.最后,几个返回大量内存的程序可能会绕过malloc()并简单地分配和释放页面.