Linux C 获取系统及进程内存状态
一、系统内存
Linux 提供了诸多的方式来获取系统内存状态。在 shell 下,我们可以通过 free 或者 top 等命令来获取。但是在 C/C++ 程序中又该如何获取呢?
这就不得不提到 Linux 提供的 proc 虚拟文件系统了,它提供了一个在 linux 内核空间和用户间之间进行通信的窗口。通过这个窗口,内核可以告诉我们很多系统信息。其中涉及到系统内存的,主要是 /proc/meminfo 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | $ cat /proc/meminfo MemTotal: 32832432 kB MemFree: 5656644 kB MemAvailable: 30807964 kB Buffers: 1514936 kB Cached: 19598868 kB SwapCached: 27880 kB Active: 7710072 kB Inactive: 14251504 kB Active(anon): 28040 kB Inactive(anon): 837312 kB Active(file): 7682032 kB Inactive(file): 13414192 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 33451004 kB SwapFree: 33249716 kB Dirty: 28 kB Writeback: 0 kB AnonPages: 823440 kB Mapped: 49736 kB Shmem: 17520 kB Slab: 4897524 kB SReclaimable: 4392968 kB SUnreclaim: 504556 kB KernelStack: 19936 kB PageTables: 37868 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 49867220 kB Committed_AS: 4098292 kB VmallocTotal: 34359738367 kB VmallocUsed: 367240 kB VmallocChunk: 34342446360 kB HardwareCorrupted: 0 kB AnonHugePages: 20480 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 111504 kB DirectMap2M: 5029888 kB DirectMap1G: 30408704 kB |
该文件告诉我们关于系统内存的全方位的信息。于是通过读取并解析该文件,就可以到达获取内存状态的目的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <sys/sysinfo.h> #include <unistd.h> #include <ctype.h> #include <string> #include <fstream> #include <sstream> #include <iostream> #include <algorithm> void get_mem_info() { unsigned long mem_free = 0; unsigned long buffers = 0; unsigned long cached = 0; unsigned long swap_free = 0; std::string tmp_str1, tmp_str2; std::ifstream infile("/proc/meminfo"); std::string line; while (std::getline(infile, line)) { std::istringstream iss(line); if (line.find("MemFree") != std::string::npos) { if (!(iss >> tmp_str1 >> mem_free >> tmp_str2)) { break; } // error } else if (line.find("Buffers") != std::string::npos) { if (!(iss >> tmp_str1 >> buffers >> tmp_str2)) { break; } // error } else if (line.find("Cached") != std::string::npos && line.find("SwapCached") == std::string::npos) { if (!(iss >> tmp_str1 >> cached >> tmp_str2)) { break; } // error } else if (line.find("SwapFree") != std::string::npos) { if (!(iss >> tmp_str1 >> swap_free >> tmp_str2)) { break; } // error } } infile.close(); std::cout << "MemFree: " << mem_free << " KB" << std::endl; std::cout << "Buffers: " << buffers << " KB" << std::endl; std::cout << "Cached: " << cached << " KB" << std::endl; std::cout << "SwapFree: " << swap_free << " KB" << std::endl; } |
如果我们只是想获取一些常见的内存状态,比如 RAM Free,不需要知道太多细节,那么使用 GNU C 提供 sysinfo 函数是一个不错的方案。
头文件 <sys/sysinfo.h> 中声明了 sysinfo 函数,并定义了 sysinfo 结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | struct sysinfo { long uptime; // Seconds since boot unsigned long loads[3]; // 1, 5, and 15 minute load averages unsigned long totalram; // Total usable main memory size unsigned long freeram; // Available memory size unsigned long sharedram; // Amount of shared memory unsigned long bufferram; // Memory used by buffers unsigned long totalswap; // Total swap space size unsigned long freeswap; // swap space still available unsigned short procs; // Number of current processes unsigned long totalhigh; // Total high memory size unsigned long freehigh; // Available high memory size unsigned int mem_unit; // Memory unit size in bytes char _f[20-2*sizeof(long)-sizeof(int)]; // Padding for libc5 }; |
通过 sysinfo 函数,我们可以获取上述系统状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void get_system_info() { struct sysinfo info; memset(&info, 0, sizeof(info)); sysinfo(&info); std::cout << "info.loads[0] = " << info.loads[0] << " KB" << std::endl; std::cout << "info.loads[1] = " << info.loads[1] << " KB" << std::endl; std::cout << "info.loads[2] = " << info.loads[2] << " KB" << std::endl; std::cout << "info.totalram = " << info.totalram << " KB" << std::endl; std::cout << "info.freeram = " << info.freeram << " KB" << std::endl; std::cout << "info.sharedram = " << info.sharedram << " KB" << std::endl; std::cout << "info.bufferram = " << info.bufferram << " KB" << std::endl; std::cout << "info.totalswap = " << info.totalswap << " KB" << std::endl; std::cout << "info.freeswap = " << info.freeswap << " KB" << std::endl; std::cout << "info.totalhigh = " << info.totalhigh << " KB" << std::endl; std::cout << "info.freehigh = " << info.freehigh << " KB" << std::endl; std::cout << "info.procs = " << info.procs << std::endl; } |
二、进程内存
进程的内存状态就相对比较复杂了,后续待补充。。。