linux cma内存,计算 Linux 内存使用率方法及C实现

通过获取Linux中的 /proc/stat 文件中的内容可以获取系统内存的详细信息:# cat /proc/meminfo

MemTotal: 3880404 kB

MemFree: 3182248 kB

MemAvailable: 3396580 kB

Buffers: 39588 kB

Cached: 355616 kB

SwapCached: 0 kB

Active: 318708 kB

Inactive: 252380 kB

Active(anon): 176120 kB

Inactive(anon): 248 kB

Active(file): 142588 kB

Inactive(file): 252132 kB

Unevictable: 0 kB

Mlocked: 0 kB

SwapTotal: 0 kB

SwapFree: 0 kB

Dirty: 0 kB

Writeback: 0 kB

AnonPages: 175940 kB

Mapped: 54184 kB

Shmem: 488 kB

Slab: 62040 kB

SReclaimable: 48712 kB

SUnreclaim: 13328 kB

KernelStack: 2672 kB

PageTables: 6080 kB

NFS_Unstable: 0 kB

Bounce: 0 kB

WritebackTmp: 0 kB

CommitLimit: 1940200 kB

Committed_AS: 615340 kB

VmallocTotal: 34359738367 kB

VmallocUsed: 14160 kB

VmallocChunk: 34359715580 kB

HardwareCorrupted: 0 kB

AnonHugePages: 36864 kB

CmaTotal: 0 kB

CmaFree: 0 kB

HugePages_Total: 0

HugePages_Free: 0

HugePages_Rsvd: 0

HugePages_Surp: 0

Hugepagesize: 2048 kB

DirectMap4k: 53120 kB

DirectMap2M: 3092480 kB

DirectMap1G: 3145728 kB

各字段含义见下表:指标作用MemTotal总内存大小

MemFree空闲内存大小

buffers/cached磁盘缓存的大小

MemAvailable可用内存大小

SwapTotal可用的swap空间的总的大小。

SwapFree剩余swap空间的大小。

Dirty需要写入磁盘的内存区大小。

Writeback正在被写回磁盘的大小。

AnonPages未映射页的内存大小。

Mapped设备和文件等映射的大小。

Slab内核数据结构slab的大小,可以减少申请和释放内存带来的消耗。注Buffers 和 Cached的区别

Buffers 是指用来给块设备做的缓冲大小,他只记录文件系统的metadata以及 tracking in-flight pages. cached 是用来给文件做缓冲。

buffers 是值存储目录里面有什么内容,权限等等。 而cached直接用来记忆我们打开的文件,比如先后执行两次命令#man X ,你就可以明显的感觉到第二次的开打的速度快很多。 而buffers随时都在增加,比如先后两次使用ls /dev后,就会发现第二次执行的速度会较第一次快。 这就是buffers/chached的区别。以内核态来讲, buffers  和 cached  是已经被使用的,可用内存就是 MemAvailableMemUsed = MemTotal - MemFree以用户态来讲,buffers  和 cached  可被分配。free = MemFree + Buffers + Cahched本着监控应用对物理内存使用情况的目的采集,计算方法:MemUsedPrec = 100*(MemTotal - MemFree - Buffers - Cahched)/MemTotal

黑洞

48a4186aba7b10c3a14861f56a2d0cb7.png    经过一番计算,发现 /proc/meminfo 中的数据无论如何无法与 free 中的内容对应,尤其是在 used 部分。经过一番信息检索,得出一个结论, free 命令中的数值是按照 /proc/meminfo 中的数据,根据一定算法计算所得,并且新版旧版的 free 所输出内容也不一致。因此按照 proc/meminfo 中的数据计算内存使用率是更加精确的。

进一步探索,会发现 Linux 存在一个内存黑洞,在某博主博客找到如下描述:追踪Linux系统的内存使用一直是个难题,很多人试着把能想到的各种内存消耗都加在一起,kernel text、kernel modules、buffer、cache、slab、page table、process RSS…等等,却总是与物理内存的大小对不上,这是为什么呢?因为Linux kernel并没有滴水不漏地统计所有的内存分配,kernel动态分配的内存中就有一部分没有计入/proc/meminfo中。

—— 《/PROC/MEMINFO之谜》

综上原因,计算Linux内存使用率也就没有必要去细扣每个数值的含义了,大致了解如下内容即可:MemTotal:总内存大小

MemFree: 空闲内存大小

buffers/cached: 磁盘缓存的大小

MemAvailable: 可用内存大小

而计算内存使用率只需按照这个方法计算:实际可挪用的内存数: free+cache+buffer,

实际可使用的内存数: used-cache-buffer (total-free-cache-buffer)。

内存占用率:(total-available) / total * 100

C实现

同样的, 先定义一个结构体用于存放相关数据:struct MEM_INFO

{

unsigned int total;

unsigned int free;

unsigned int buffers;

unsigned int cached;

unsigned int swap_cached;

unsigned int swap_total;

unsigned int swap_free;

unsigned int available;

};

typedef struct MEM_INFO Mem_info;

之后定义函数,用于获取及计算内存数据:void get_mem_occupy (Mem_info *o)

{

FILE* fpMemInfo = fopen("/proc/meminfo", "r");

if (NULL == fpMemInfo)

{

return ;

}

int i = 0;

int value;

char name[1024];

char line[1024];

int nFiledNumber = 2;

int nMemberNumber = 5;

while (fgets(line, sizeof(line) - 1, fpMemInfo))

{

if (sscanf(line, "%s%u", name, &value) != nFiledNumber)

{

continue;

}

if (0 == strcmp(name, "MemTotal:"))

{

++i;

o->total = value;

}

else if (0 == strcmp(name, "MemFree:"))

{

++i;

o->free = value;

}

else if (0 == strcmp(name, "MemAvailable:"))

{

++i;

o->available = value;

}

else if (0 == strcmp(name, "Buffers:"))

{

++i;

o->buffers = value;

}

else if (0 == strcmp(name, "Cached:"))

{

++i;

o->cached = value;

}

if (i == nMemberNumber)

{

break;

}

}

// system("free");

// system("cat /proc/meminfo");

// printf("MemTotal : %d\n",o->total);

// printf("MemFree : %d\n",o->free);

// printf("MemAvailable : %d\n",o->available);

// printf("MemBuffers : %d\n",o->buffers);

// printf("MemCached : %d\n",o->cached);

// printf("MemSwapCached : %d\n",o->swap_cached);

// printf("MemSwapTotal : %d\n",o->swap_total);

// printf("MemSwapFree : %d\n",o->swap_free);

fclose(fpMemInfo);

}

float cal_mem_occupy(Mem_info *o)

{

return (100.0 * (o->total - o->available) / o->total);

}

最后调用即可:Mem_info omem;

while(1)

{

// printf("-------------------- Mem occupy -------------------\n");

get_mem_occupy(&omem);

printf("Mem Usage(%): %8.4f\n", cal_mem_occupy(&omem));

printf("\n");

}

参考文献

---------------------

Author: Frytea

Title: 计算 Linux 内存使用率方法及C实现

Link: https://blog.frytea.com/archives/405/

Copyright: This work by TL-Song is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

c216a654f63949ea4313f31d292441e3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值