linux获取内存与cpu使用率(附有C语言源码与shell脚本) |
您所在的位置:网站首页 › vmalloctotal › linux获取内存与cpu使用率(附有C语言源码与shell脚本) |
一、获取内存信息的方法
linux内核提供了一种通过/proc文件系统来在运行时访问内核内部数据结构,改变内核设置的机制,各种硬件平台上的linux系统的/proc文件系统的基本概念都是相同的。 /proc文件系统是一种内核和内核模块用来向进程发送信息的机制。这个伪文件系统可以和内核内部的数据结构进行交互,获取实时的进程信息。注意,/proc文件系统是存储与内存而不是硬盘,/proc虚拟文件系统实质是以文件系统的形式访问内核数据的接口。 /proc/meminfo linux系统中/proc/meminfo这个文件用来记录了系统内存使用的详细情况。其中top,free命令中的数据是通过这个文件中的信息计算并按照特定的格式进行显示。 命令解析 MemTotal: 所有内存(RAM)大小,减去一些预留空间和内核的大小。 MemFree: 完全没有用到的物理内存,lowFree+highFree MemAvailable: 在不使用交换空间的情况下,启动一个新的应用最大可用内存的大小,计算方式:MemFree+Active(file)+Inactive(file)-(watermark+min(watermark,Active(file)+Inactive(file)/2)) Buffers: 块设备所占用的缓存页,包括:直接读写块设备以及文件系统元数据(metadata),比如superblock使用的缓存页。 Cached: 表示普通文件数据所占用的缓存页。 SwapCached: swap cache中包含的是被确定要swapping换页,但是尚未写入物理交换区的匿名内存页。那些匿名内存页,比如用户进程malloc申请的内存页是没有关联任何文件的,如果发生swapping换页,这类内存会被写入到交换区。 Active: active包含active anon和active file Inactive: inactive包含inactive anon和inactive file Active(anon): anonymous pages(匿名页),用户进程的内存页分为两种:与文件关联的内存页(比如程序文件,数据文件对应的内存页)和与内存无关的内存页(比如进程的堆栈,用malloc申请的内存),前者称为file pages或mapped pages,后者称为匿名页。 Inactive(anon): 见上 Active(file): 见上 Inactive(file): 见上 SwapTotal: 可用的swap空间的总的大小(swap分区在物理内存不够的情况下,把硬盘空间的一部分释放出来,以供当前程序使用) SwapFree: 当前剩余的swap的大小 Dirty: 需要写入磁盘的内存去的大小 Writeback: 正在被写回的内存区的大小 AnonPages: 未映射页的内存的大小 Mapped: 设备和文件等映射的大小 Slab: 内核数据结构slab的大小 SReclaimable: 可回收的slab的大小 SUnreclaim: 不可回收的slab的大小 PageTables: 管理内存页页面的大小 NFS_Unstable: 不稳定页表的大小 VmallocTotal: Vmalloc内存区的大小 VmallocUsed: 已用Vmalloc内存区的大小 VmallocChunk: vmalloc区可用的连续最大快的大小内存的使用率的计算方法 proc/stat节点记录的是系统进程整体的统计信息 wyy$ cat /proc/stat //CPU指标:user,nice, system, idle, iowait, irq, softirq cpu 130216 19944 162525 1491240 3784 24749 17773 0 0 0 cpu0 40321 11452 49784 403099 2615 6076 6748 0 0 0 cpu1 26585 2425 36639 151166 404 2533 3541 0 0 0 cpu2 22555 2957 31482 152460 330 2236 2473 0 0 0 cpu3 15232 1243 20945 153740 303 1985 3432 0 0 0 cpu4 5903 595 6017 157410 30 10959 605 0 0 0 cpu5 4716 380 3794 157909 23 118 181 0 0 0 cpu6 8001 515 8995 157571 48 571 180 0 0 0 cpu7 6903 377 4869 157885 31 271 613 0 0 0 intr ... ctxt 22523049 btime 1500827856 processes 23231 procs_running 1 procs_blocked 0 softirq 3552900 843593 733695 19691 93143 468832 12783 257382 610426 0 513355有以上信息能够得出 cpu是4核的,cpu这项相应信息例如以下 cpu user nice system idle iowait irq softirq steal guest guest_nice user:用户态的CPU时间 nice:低优先级程序所占用的用户态的cpu时间。 system:系统态的CPU时间 idle:CPU空暇的时间(不包括IO等待) iowait:等待IO响应的时间 irq:处理硬件中断的时间 softirq:处理软中断的时间 steal:其它系统所花的时间(个人理解是针对虚拟机) guest:执行时间为客户操作系统下的虚拟CPU控制(个人理解是访客控制CPU的时间) guest_nice:低优先级程序所占用的用户态的cpu时间。 三、c语言程序测试内存与CPU使用率 #include #include #include typedef struct PACKED //定义一个cpu occupy的结构体 { char name[20]; //定义一个char类型的数组名name有20个元素 unsigned int user; //定义一个无符号的int类型的user unsigned int nice; //定义一个无符号的int类型的nice unsigned int system;//定义一个无符号的int类型的system unsigned int idle; //定义一个无符号的int类型的idle }CPU_OCCUPY; typedef struct PACKED1 //定义一个mem occupy的结构体 { char name[20]; //定义一个char类型的数组名name有20个元素 unsigned long total; char name2[20]; unsigned long free; }MEM_OCCUPY; /*获取内存使用率*/ int get_memoccupy (MEM_OCCUPY *mem) //对无类型get函数含有一个形参结构体类弄的指针O { FILE *fd; int n; char buff[256]; char buff1[256]; char buff2[256]; char buff3[256]; char buff4[256]; MEM_OCCUPY *m; m=mem; float mem_use; fd = fopen ("/proc/meminfo", "r"); fgets (buff1, sizeof(buff1), fd); printf("%s\n",buff1); int num1 = atoi(buff1+15); printf("%d\n",num1); fgets (buff2, sizeof(buff2), fd); printf("%s\n",buff2); int num2 = atoi(buff2+15); fgets (buff3, sizeof(buff3), fd); printf("%s\n",buff3); int num3 = atoi(buff3+15); fgets (buff4, sizeof(buff4), fd); // sscanf (buff, "%s %u %s", m->name, &m->total, m->name2); printf("%s\n",buff4); int num4 = atoi(buff4+15); fgets (buff, sizeof(buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里 printf("%s\n",buff); int num5 = atoi(buff+15); // 内存使用率(MEMUsedPerc)=100*(MemTotal-MemFree-Buffers-Cached)/MemTotal mem_use = (float)100*(num1-num2-num5-num4)/num1; printf("内存使用率为:%.2f%%\n",mem_use); fclose(fd); //关闭文件fd } /*获取cpu使用率*/ float cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n) { unsigned long od, nd; unsigned long id, sd; float cpu_use = 0; od = (unsigned long) (o->user + o->nice + o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od nd = (unsigned long) (n->user + n->nice + n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给nd id = (unsigned long) (n->user - o->user); //用户第一次和第二次的时间之差再赋给id sd = (unsigned long) (n->system - o->system);//系统第一次和第二次的时间之差再赋给sd if((nd-od) != 0) { cpu_use = (float)((sd+id)*100)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used } else { cpu_use = 0; } printf("cpu使用率为:%1.2f%%\n",cpu_use); return cpu_use; } void get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针O { FILE *fd; int n; char buff[256]; CPU_OCCUPY *cpu_occupy; cpu_occupy=cpust; fd = fopen ("/proc/stat", "r"); fgets (buff, sizeof(buff), fd); sscanf (buff, "%s %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice,&cpu_occupy->system, &cpu_occupy->idle); fclose(fd); } int main() { CPU_OCCUPY cpu_stat1; CPU_OCCUPY cpu_stat2; MEM_OCCUPY mem_stat; float cpu; //获取内存 get_memoccupy ((MEM_OCCUPY *)&mem_stat); //第一次获取cpu使用情况 get_cpuoccupy((CPU_OCCUPY *)&cpu_stat1); sleep(10); //第二次获取cpu使用情况 get_cpuoccupy((CPU_OCCUPY *)&cpu_stat2); //计算cpu使用率 cpu = cal_cpuoccupy ((CPU_OCCUPY *)&cpu_stat1, (CPU_OCCUPY *)&cpu_stat2); return 0; }测试结果: 脚本结果如下: top命令: us:用户空间占用CPU百分比 sy:内核空间占用CPU百分比 ni:用户进程空间内改变过优先级的进程占用CPU百分比 id:空闲CPU百分比 wa:等待输入输出的CPU时间百分比 hi:硬件中断 si:软件中断 st:虚拟机占用物理机的百分比 我想要获得CPU当前占用率,只需要使用100减去空闲CPU即可。 使用awk命令获取空闲CPU。awk默认按空格切割字符串,根据下图显示可以确认id的数值在第8个,使用100减去该值即可获取当前CPU占用率,所以使用命令“top -n1 | fgrep “Cpu(s)” | awk ‘{print 100-$8}’”,显示如下图所示: |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |