本博文为原创,遵循CC3.0协议,转载请注明出处:http://blog.csdn.net/lux_veritas/article/details/19231993
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1. free -m
2. 用户态程序中,利用sysinfo系统调用
3. 内核态程序中,我没有找到很好的方法,通过追踪sysinfo系统调用的流程,定位实现函数。最终利用do_sysinfo中的si_meminfo实现
linux系统中,查看当前内存的使用情况,简便的方法是free命令,命令行中free -m,列出系统当前的可用内存、cache/buffer、swap相关信息。
free工具是procps项目提供的标准proc文件系统分析工具,通过读取分析/proc/meminfo,实时的反应当前系统的内存使用情况。项目主页:procps.sourceforge.net
如果想在程序中实时查看系统当前可用内存情况,可以利用的方法也是多样的。
1. 如果是在用户态程序中查看,可以通过“system”系统调用,执行free命令,或是读取/proc/meminfo文件,再做文本处理。
2. 当然1的方法不够直观,/proc/meminfo中的信息是系统利用proc文件系统的处理函数获得的,内核代码fs/proc/meminfo.c中实现的。
粗读代码可以发现struct sysinfo这个结构(include/linux/kernel.h中定义)
struct sysinfo { long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ unsigned short pad; /* explicit padding for m68k */ unsigned long totalhigh; /* Total high memory size */ unsigned long freehigh; /* Available high memory size */ unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ };
可以看到该结构中定义了系统的内存使用情况。源码中查询sysinfo,发现有sysinfo这个系统调用,用于查询和获得系统信息。
于是在用户态程序中可以采用如下方法:
#include <stdio.h> #include <unistd.h> #include <linux/kernel.h> int main() { struct sysinfo *sys; int err = sysinfo(sys); printf("\n\nerror code is: %d\n", err); printf( "free mem:\t%ld\n" "total mem:\t%ld\n" "buffer mem:\t%ld\n", sys->freeram, sys->totalram, sys->bufferram ); return 0; }
SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info)宏展开SYSCALL_DEFINE1得到验证。
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; }
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; }
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/mm.h> #include <asm/page.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("GuoHongwei"); static int sysinfo_init() { struct sysinfo sys; // int err = do_sysinfo(&sys); si_meminfo(&sys); // printk("\n\nerror code is: %ld", err); printk("free mem is: %ld\n", (sys.freeram << (PAGE_SHIFT - 10))); return 0; } static void sysinfo_exit() { printk("exit module sysinfo_test\n"); } module_init(sysinfo_init); module_exit(sysinfo_exit);
obj-m := sysinfo_test.o KERNELDIR = /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: make -C $(KERNELDIR) M=$(PWD) modules clean: make -C $(KERNELDIR) M=$(PWD) clean
执行结果如下:
原文:http://blog.csdn.net/lux_veritas/article/details/19231993