free命令是linux系统中常用来查看内存大概情况的shell命令,其执行的效果如下:
root@mimosa_24FD52F24E00:/# free
total used free shared buffers
Mem: 61056 34296 26760 0 3776
-/+ buffers: 30520 30536
Swap: 0 0 0
root@mimosa_24FD52F24E00:/#
(这个输出的基本单位为KB)
free这个结果的产生由调用sysinfo()系统调用函数得到对应的结果,在2.6.36内核中跟踪的结果如下:
[kernel/timer.c]
SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info)
{
struct sysinfo val;
do_sysinfo(&val);
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
return -EFAULT;
return 0;
}
sysinfo()系统调用最终由上面的函数给出内核的统计值。
其中,do_sysinfo()函数的实现也在同一文件中,其定义的部分内容如下:
[kernel/timer.c: sysinfo()->do_sysinfo()]
/**
* do_sysinfo - fill in sysinfo struct
* @info: pointer to buffer to fill
*/
int do_sysinfo(struct sysinfo *info)
{
...
si_meminfo(info);
...
bitcount = 0;
mem_unit = info->mem_unit;
while (mem_unit > 1) {
bitcount++;
mem_unit >>= 1;
sav_total = mem_total;
mem_total <<= 1;
if (mem_total < sav_total)
goto out;
}
/*
* If mem_total did not overflow, multiply all memory values by
* info->mem_unit and set it to 1. This leaves things compatible
* with 2.2.x, and also retains compatibility with earlier 2.4.x
* kernels...
*/
info->mem_unit = 1;
info->totalram <<= bitcount;
info->freeram <<= bitcount;
info->sharedram <<= bitcount;
info->bufferram <<= bitcount;
info->totalswap <<= bitcount;
info->freeswap <<= bitcount;
info->totalhigh <<= bitcount;
info->freehigh <<= bitcount;
out:
return 0;
}
其中,do_sysinfo()调用si_meminfo()获取vm_stat[]当前的未被使用内存总量,通过global_page_state()函数获得:
[mm/page_alloc.c: sysinfo()->do_sysinfo()->si_meminfo()]
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
val->sharedram = 0;
val->freeram = global_page_state(NR_FREE_PAGES);
val->bufferram = nr_blockdev_pages();
val->totalhigh = totalhigh_pages;
val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
}
由global_page_state()函数的名称可以猜测,vm_stat对内存的管理的基本单位为页,此处为4KB内存大小。
确定了freeram的取值来源,也可以知道free命令的输出的基本单位为4KB,即free会存在最多4KB的误差。此时,若检查程序的内存泄露,对于泄露的内存远小于4KB的情况,可能需要一定时间的累加才能获知free得到的剩余内存在降低,由于系统一般在运行中,而且linux内核会尽可能地使用内存用于提高系统的执行效率,所以,要想明确得到较小内存泄露程序的证据,时间会增加很多,最终,应该是比较长时间的free结果的剩余内存的统计值处于波动降低的这么一个现象。