声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神。也欢迎大家一起探讨,交流,以共同进步,乃至成为朋友~ 0.0

/*
@url:http://www.cnblogs.com/johnnyzen/p/8011309.html
@author:Johnny Zen
@school:XiHua University
@contact:johnnyztsd@gmail.com or 1125418540@qq.com
@date:2017-12-10 13:47
@description:内存计算与辨析
@environment:Linux For Ubuntu 16.04/64
*/

计算内存利用率的引导思路

  1.手动查看内存(的各参数)状况
    cat /proc/meminfo
    其中有如下重点参数:
      MemTotal:总内存大小
      MemFree: 系统空闲内存大小,表示系统尚未使用的内存
      MemAvailable:应用程序可用内存数,应用程序可用内存数。内存可获得/可使用的存储量(注意:3.14内核新增功能)
        官网解释:    
        Many load balancing and workload placing programs check /proc/meminfo to estimate how much free memory is available. They generally do this by adding up "free" and "cached", which was fine ten years ago, but is pretty much guaranteed to be wrong today.
        It is wrong because Cached includes memory that is not freeable as page cache, for example shared memory segments, tmpfs, and ramfs, and it does not include reclaimable slab memory, which can take up a large fraction of system memory on mostly idle systems with lots of files.Currently, the amount of memory that is available for a new workload,without pushing the system into swap, can be estimated from MemFree, Active(file), Inactive(file), and SReclaimable, as well as the "low"watermarks from /proc/zoneinfo.However, this may change in the future, and user space really should not be expected to know kernel internals to come up with an estimate for the amount of free memory.It is more convenient to provide such an estimate in /proc/meminfo. If things change in the future, we only have to change it in one place.
        翻译过来:
        许多负载均衡和负载放置程序检查/proc/meminfo估计多少空闲内存。他们通常通过增加“内存自由区”和“内存缓存区”来实现这一点,这在十年前是很好的,但今天肯定是错误的。
                            因为缓存包含内存不可用的页面缓存,例如共享内存段,tmpfs,和ramfs,它不包含可回收板内存,这会占用系统内存很大一部分主要包含大量文件的怠速系统。目前,这是一个新的工作量内存量,不推系统互换,可以估算工具,积极的(文件),无效(文件),并sreclaimable,以及从/ proc / zoneinfo.however“低”的水印,这可能会在未来改变,与用户空间真的不应该知道内核到拿出空闲内存量的估算。它是提供在/proc/meminfo这样的估计更方便。如果事情在未来发生变化,我们只需要在一个地方改变它。

        即:[引用自博文 [Linux MemFree与MemAvailable的区别]:http://www.th7.cn/system/lin/201708/226350.shtml]

系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以MemFree不能代表全部可用的内存,这部分可回收的内存加上MemFree才是系统可用的内存,即:MemAvailable≈MemFree+Buffers+Cached,它是内核使用特定的算法计算出来的,是一个估计值。它与MemFree的关键区别点在于,MemFree是说的系统层面MemAvailable是说的应用程序层面

        实际意义:
        MemAvailable:MemFree+Active(file)+Inactive(file)-(watermark+min(watermark,Active(file)+Inactive(file)/2))
      Buffers:磁盘缓冲大小
      Cached:磁盘缓存大小
                    
  2.计算内存利用率公式
    MemUsed(内存(已)使用量) =  MemTotal(内存总存储量) - MemAvailable(内存可获得/可使用的存储量)
      注意:
        需要注意的是,网络上有很多"误导"(其实,也不是误导,只是站在不同的使用角度(操作系统/应用程序(用户))来说而已)教程,他们是如此认为的:
        定义:MemUsed(内存(已)使用量,不可直接算出,根据不同的使用角度/概念,计算出的结果不一致)
        这里有什么"误导"呢?
        首先,要明白MemFree(内存空闲的存储量)是怎么计算出来的:
          对【操作系统】来说,Buffers和Cached是被视为【已经被使用】的:
            原理:

            MemUsed(内存(已)使用量,包含:Buffers,Cached) =  MemTotal(内存总存储量) - MemFree(内存空闲的存储量)【结果将偏高】
            MemFree = MemTotal - MemUsed(包含:Buffers,Cached) 【结果将偏低】
            或者,这样看:    
          对【应用程序】来说,Buffers和Cached是被视为【未被使用】的:
            解释:cache属于OS管理,对应用程序是透明的                                
            原理:
            free(重定义) = MemAvailable

            MemUsed = MemTotal - MemAvailable

  3.实际使用

    理解[2]以后,就很好办了:根据编程用户的实际需要,计算内存利用情况
    以【应用程序/系统内用户】的角度:
      内存使用率MemUsedPencentage = (MemTotal - MemAvailable) * 100    
      Eg:
        Free = MemAvailable = 5595176 KB
        MemUsed = 8087460 KB - 5595176 KB = 2492284 KB    
        MemUsedPencentage = ( MemUsed / MemTotal ) * 100 = 30.816647(%)

  4.验证

    打开Linux For Ubuntu 系统检测查看

    [公式计算的数据属于历史数据,所以与上式计算结果有出入。下图中的是实时截图数据,其左侧,属于【用户角度/应用程序】计算的内存利用率结果,其右侧属于【操作系统角度】所上计算出的内存利用率结果]

    

  5.编程实现

/*
@url:http://www.cnblogs.com/johnnyzen/p/8011309.html
@author:Johnny Zen
@school:XiHua University
@contact:johnnyztsd@gmail.com or 1125418540@qq.com
@date:2017-12-10 14:53
@description:本程序分别计算从【操作系统/用户角度】计算出的内存利用情况
@environment:Linux For Ubuntu 16.04/64
/
关于[内存利用率的计算与辨析]已写入个人博客,详见:
[Linux之计算内存利用率与辨析 ]http://www.cnblogs.com/johnnyzen/p/8011309.html
关于[Linux虚拟文件系统/proc的概述性理解]也已写入个人博客,详见:
[Linux之虚拟文件系统[/proc]中关于CPU/内存/网络/内核等的一些概要性说明]:http://www.cnblogs.com/johnnyzen/p/8011374.html
/
*/
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MemTotal_LINE_NUMBER 1 //内存【总存储空间】所处行数
#define MemFree_LINE_NUMBER 2 //【内存空闲存储空间数据】(对于应用程序)所处行数
#define MemAvailable_LINE_NUMBER 3 //【应用程序可利用】的内存存储空间数所处行数
//[注意:MemAvailable_LINE_NUMBER 必须大于 MemTotal_LINE_NUMBER,否则读取数据处代码将会产生读取数据失败等异常结果] //参数:TYPE:["SYSTEM_NUMMERIC/SYSTEM_PERCENTAGE/APPLiCATION_NUMMERIC/APPLiCATION_PERCENTAGE"]
float mem_usage(char * TYPE){
FILE *mem_stream;
char mem_buffer[256];//缓冲区
char memTotal_line[256];//内存总数
char memFree_line[256]; //空闲内存数
char file[64] = {"/proc/meminfo"};//要读取的目标文件名
mem_stream = fopen (file, "r"); //以R读的方式打开文件再赋给指针fd char tmp_itemName[32];//临时存放文件中的项目名称
int memTotal;//存放内存总数(单位:KB)
int memFree; //存放空闲内存数(单位:KB)
int memAvailable;//存放应用程序的可利用内存存储空间大小(单位:KB)
int memUsed;
//计算已经使用的内存(数值)(分别从用户/应用程序(memAvailable)角度或者操作系统(memFree)角度计算)
float result; //函数返回值
//读取数据
char *line_return;//记录读取每行的时候的返回结果(NULL或者返回mem_buffer)
for(int i = 0; i < MemAvailable_LINE_NUMBER; i++){
line_return = fgets (mem_buffer, sizeof(mem_buffer), mem_stream);
if(i == (MemTotal_LINE_NUMBER -1)){
if(line_return != NULL){//读取成功
sscanf(mem_buffer, "%s%d", tmp_itemName, &memTotal);
} else {
printf("[mem_usage] Read File in line %d Fail!", MemTotal_LINE_NUMBER);
exit(1);
}
} else if(i == (MemFree_LINE_NUMBER - 1)) {
if(line_return != NULL){//读取成功
sscanf(mem_buffer, "%s%d", tmp_itemName, &memFree);
} else {
printf("[mem_usage] Read File in line %d Fail!", MemFree_LINE_NUMBER);
exit(1);
}
} else if(i == (MemAvailable_LINE_NUMBER - 1)){
if(line_return != NULL){//读取成功
sscanf(mem_buffer, "%s%d", tmp_itemName, &memAvailable);
} else {
printf("[mem_usage] Read File in line %d Fail!", MemAvailable_LINE_NUMBER);
exit(1);
}
}
} fclose(mem_stream); //关闭文件mem_stream if(TYPE == "SYSTEM_NUMMERIC"){
memUsed = memTotal - memFree;
result = memUsed;
} else if(TYPE == "SYSTEM_PERCENTAGE"){
memUsed = memTotal - memFree;
result = (((float) memUsed / (float)memTotal) * 100);
} else if(TYPE == "APPLiCATION_NUMMERIC"){
memUsed = memTotal - memAvailable;
result = memUsed;
} else if(TYPE == "APPLiCATION_PERCENTAGE"){
memUsed = memTotal - memAvailable;
result = (((float) memUsed / (float)memTotal) * 100);
} printf("\n[MEM] System memTotal: %d KB.\n", memTotal);
printf("[MEM] System memFree: %d KB.\n", memFree);
printf("[MEM] System memUsed: %d KB.\n", (memTotal - memFree));
printf("[MEM] APPLiCATION memUsed: %d KB.\n", (memTotal - memAvailable)); return result;
} //demo
int main(){ printf("\n[MAIN MEM] MEM SYSTEM Usage PERCENTAGE: %.2f %s.\n\n",
mem_usage("SYSTEM_PERCENTAGE"), "%");
printf("\n[MAIN MEM] MEM SYSTEM Total Used Usage: %.2f %s.\n\n",
mem_usage("SYSTEM_NUMMERIC"), "KB");
printf("\n[MAIN MEM] MEM APPLiCATION Usage PERCENTAGE: %.2f %s.\n\n",
mem_usage("APPLiCATION_PERCENTAGE"), "%");
printf("\n[MAIN MEM] MEM APPLiCATION Total Used Usage: %.2f %s.\n\n",
mem_usage("APPLiCATION_NUMMERIC"), "KB"); return 0;
}

  运行效果:

参考文献
  [proc/meminfo 文件内存详解]:http://blog.csdn.net/u014089131/article/details/52814516

  [linux 计算内存使用率]:http://blog.csdn.net/u010807846/article/details/40919393(博主认为,其观点不尽是全正确的,例如最后的结论,但仍有很多可取的观点)

  [Linux MemFree与MemAvailable的区别]:http://www.th7.cn/system/lin/201708/226350.shtml

[C++]Linux之计算内存利用率与辨析的更多相关文章

  1. linux系统性能监控--内存利用率

    Linux提供了对物理内存进行合理.高效的访问并可以访问潜在的海量虚存的技术.虚存通常稍多于操作系统实际拥有的内存容量,以便将较少使用的数据卸载到磁盘存储器上,同时又呈现出系统拥有大量物理内存的假象. ...

  2. Linux下计算进程的CPU占用和内存占用的编程方法[转]

    from:https://www.cnblogs.com/cxjchen/archive/2013/03/30/2990548.html Linux下没有直接可以调用系统函数知道CPU占用和内存占用. ...

  3. linux概念之内存分析

    linux内存总结 分析样本[root@-comecs ~]# free total used free shared buffers cached Mem: -/+ buffers/cache: S ...

  4. Linux安装时内存如何分区的相关问题

    Linux系统安装时内存如何分区:Linux系统必须的分区是根分区(/)和swap交换分区.普通用户一般分三个区,一个根分区(/),一个家目录(home分区),一个交换分区(swap分区),以80G的 ...

  5. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  6. 如何在linux下检测内存泄漏

    之前的文章应用 Valgrind 发现 Linux 程序的内存问题中介绍了利用Linux系统工具valgrind检测内存泄露的简单用法,本文实现了一个检测内存泄露的工具,包括了原理说明以及实现细节. ...

  7. Linux kernel学习-内存管理【转】

    转自:https://zohead.com/archives/linux-kernel-learning-memory-management/ 本文同步自(如浏览不正常请点击跳转):https://z ...

  8. 转载: 一、linux cpu、内存、IO、网络的测试工具

    来源地址: http://blog.csdn.net/wenwenxiong/article/details/77197997 记录一下 以后好找.. 一.linux cpu.内存.IO.网络的测试工 ...

  9. Linux kernel学习-内存管理

    转自:https://zohead.com/archives/linux-kernel-learning-memory-management/ 本文同步自(如浏览不正常请点击跳转):https://z ...

随机推荐

  1. NowCoder--牛客练习赛30 C_小K的疑惑

    题目链接 :牛客练习赛30 C_小K的疑惑 i j k 可以相同 而且 距离%2 只有 0 1两种情况 我们考虑 因为要 d(i j)=d(i k)=d(j k) 所以我们只能找 要么三个点 任意两个 ...

  2. bzoj1218 激光炸弹

    bz上难得一见的水题啊. 我们发现:这个SB居然只要枚举就行了!!! 我TM...... /****************************************************** ...

  3. POJ 2449 Remmarguts' Date (第k短路径)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions:35025   Accepted: 9467 ...

  4. 关于python类变量和实例变量

    今天在看python的类和实例的时候,突然发现了一个以前遗漏的点,也就是类变量和实例变量.首先需要理解一下类变量和实例变量的概念. 类全局变量:在类中定义,对类和由类生成的实例生效,如果通过方法对类变 ...

  5. php 4种传值方式

    我们定义page01.php和page02.php两个php文件,将page01中的内容想办法传递到page02,然后供我们继续使用. 第一种:     使用客户端浏览器的cookie.cookie很 ...

  6. CentOS上手工部署kubernetes集群

    本文完全是根据二进制部署kubernets集群的所有步骤,同时开启了集群的TLS安全认证. 环境说明 在下面的步骤中,我们将在三台CentOS系统的物理机上部署具有三个节点的kubernetes1.7 ...

  7. javaweb简单登陆例子

    JSP+Servlet+JavaBean简单程序例子——用户名密码登陆,摘自<Tomcat&JavaWeb 技术手册>,亲测可用. IDE环境:MyEclipse10 1.建立We ...

  8. C#设计模式(12)——组合模式

    1.组合模式 在软件开发中我们经常会遇到处理部分与整体的情况,如我们经常见到的树形菜单,一个菜单项的子节点可以指向具体的内容,也可以是子菜单.类似的情况还有文件夹,文件夹的下级可以是文件夹也可以是文件 ...

  9. Web API中给领域模型添加媒体类型支持

    一.媒体类型 媒体类型(也称为MIME类型)标识一段数据的格式.在HTTP中,媒体类型描述了消息体的格式.媒体类型由两个字符串组成,一个类型和一个子类型.例如:text / html: image/ ...

  10. MySQL mysqldump与source导入慢的解决方法

    Jquery中文网 >  数据库  >  mysql  >  正文 MySQL mysqldump与source导入慢的解决方法 MySQL mysqldump与source导入慢的 ...