获取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)