Linux 真实使用内存计算

获取Linux内存信息,可通过cat /proc/meminfo查看,比如,Ubuntu 20.04.5 LTS上会显示以下信息:

leoya@DESKTOP-LMR:~$ cat /proc/meminfo
MemTotal:       16017572 kB
MemFree:        15637472 kB
MemAvailable:   15533140 kB
Buffers:           19964 kB
Cached:            77928 kB
SwapCached:            0 kB
Active:            37444 kB
Inactive:          82628 kB
Active(anon):        164 kB
Inactive(anon):    22308 kB
Active(file):      37280 kB
Inactive(file):    60320 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4194304 kB
SwapFree:        4194304 kB
Dirty:              1024 kB
Writeback:             0 kB
AnonPages:         22192 kB
Mapped:            21932 kB
Shmem:               284 kB
KReclaimable:      20232 kB
Slab:              50776 kB
SReclaimable:      20232 kB
SUnreclaim:        30544 kB
KernelStack:        3152 kB
PageTables:          748 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    12203088 kB
Committed_AS:     241884 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       23736 kB
VmallocChunk:          0 kB
Percpu:             5568 kB
AnonHugePages:     10240 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:       19456 kB
DirectMap2M:     4851712 kB
DirectMap1G:    19922944 kB

一般来说,MemTotal代表总内存,MemFree代表系统层面剩余内存,MemAvailable代表应用层面可用内存,可能在这里就有点迷糊了,真实的可用内存以及使用内存应该是什么?

通过查阅相关资料,国外大佬已经给出答案:

// 已使用内存
Used RAM = MemTotal - (MemFree+Buffers+SReclaimable+Cached-Shmem)

故:

这将打印 Linux 上实际使用的(不可回收的)内存量,单位为兆字节。

#include <stdio.h>
#include <string.h>

int main() {
    
    

	unsigned long int div = 1024;
	unsigned long int memtotal = 0, memfree = 0, buffers = 0, cached = 0, shmem = 0, sreclaimable = 0;
	FILE *meminfo_fp;
	char buf[256]; /* any line in /proc/meminfo longer than this would get truncated; wouldn't happen */

	if (!(meminfo_fp = fopen("/proc/meminfo", "r"))) {
    
    
		fprintf(stderr, "can't open /proc/meminfo");
		return 1;
	}

	while (!feof(meminfo_fp)) {
    
    
		if (fgets(buf, 255, meminfo_fp) == NULL) {
    
    
			break;
		}

		if (strncmp(buf, "MemTotal:", 9) == 0) {
    
    
			sscanf(buf, "%*s %lu", &memtotal);
		} else if (strncmp(buf, "MemFree:", 8) == 0) {
    
    
			sscanf(buf, "%*s %lu", &memfree);
		} else if (strncmp(buf, "Buffers:", 8) == 0) {
    
    
			sscanf(buf, "%*s %lu", &buffers);
		} else if (strncmp(buf, "Cached:", 7) == 0) {
    
    
			sscanf(buf, "%*s %lu", &cached);
		} else if (strncmp(buf, "Shmem:", 6) == 0) {
    
    
			sscanf(buf, "%*s %lu", &shmem);
		} else if (strncmp(buf, "SReclaimable:", 13) == 0) {
    
    
			sscanf(buf, "%*s %lu", &sreclaimable);
		}
	}

	fclose(meminfo_fp);

	printf("%lu\n", ( memtotal - (memfree + buffers + sreclaimable + (cached - shmem)) ) / div );

	return 0;
}

我也查阅了相关开源项目的代码,比如netdata项目也是用以上公式进行计算的:

collectors\proc.plugin\proc_meminfo.c

// http://calimeroteknik.free.fr/blag/?article20/really-used-memory-on-gnu-linux
unsigned long long MemCached = Cached + SReclaimable - Shmem;
unsigned long long MemUsed = MemTotal - MemFree - MemCached - Buffers;
// The Linux kernel doesn't report ZFS ARC usage as cache memory (the ARC is included in the total used system memory)
MemCached += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
MemUsed -= (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
MemAvailable += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);

https://github.com/netdata/netdata/blob/2d5f3acf71f0c759056a3269987fee484566bc4c/collectors/proc.plugin/proc_meminfo.c#L157-L163

在平时,可用粗略估算,如果要计算准确的内存使用率,那么可采用此方法

Really used memory on GNU/Linux - CalimeroTeknik’s Blag (free.fr)

netdata-proc_meminfo.c

/proc/meminfo 各字段详解

猜你喜欢

转载自blog.csdn.net/no_say_you_know/article/details/129236228
今日推荐