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结果的剩余内存的统计值处于波动降低的这么一个现象。