ใน Linux ข้อมูล Process Memory อยู่ใน Virtual Filesystem /proc/<PID>/stat สำหรับ Process ตัวเองใช้ /proc/self/stat ไฟล์นี้มีข้อมูลมากกว่า 50 Fields เราสนใจ 2 Fields:
- Vsize (Virtual Memory Size): Field 23 - Virtual Address Space ทั้งหมด (Bytes)
- RSS (Resident Set Size): Field 24 - Physical RAM ที่ใช้จริง (Pages)
โค้ดอ่าน Memory Usage
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h> // sysconf
void get_memory_usage(double& vm_usage_kb, double& rss_kb) {
vm_usage_kb = 0.0;
rss_kb = 0.0;
std::ifstream stat_stream("/proc/self/stat");
if (!stat_stream) return;
// อ่าน Fields 1-22 (Skip ด้วย Dummy Variables)
std::string pid, comm, state, ppid, pgrp, session, tty_nr;
std::string tpgid, flags, minflt, cminflt, majflt, cmajflt;
std::string utime, stime, cutime, cstime, priority, nice;
std::string itrealvalue, starttime;
unsigned long vsize; // Field 23: Virtual Memory (bytes)
long rss; // Field 24: Resident Set Size (pages)
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
>> utime >> stime >> cutime >> cstime >> priority >> nice
>> itrealvalue >> starttime >> vsize >> rss;
stat_stream.close();
long page_size_kb = sysconf(_SC_PAGESIZE) / 1024; // KB per Page (มัก 4 KB)
vm_usage_kb = vsize / 1024.0; // Bytes -> KB
rss_kb = rss * page_size_kb; // Pages -> KB
}
int main() {
double vm, rss;
get_memory_usage(vm, rss);
std::cout << "Virtual Memory: " << vm << " KB\n";
std::cout << "Resident Set Size: " << rss << " KB\n";
return 0;
}
ผลลัพธ์ตัวอย่าง
Virtual Memory: 13272 KB
Resident Set Size: 1548 KB
ความหมายของ Metrics
- Virtual Memory (Vsize): Address Space ที่ Process จองไว้ (รวม Code, Data, Heap, Stack, Shared Libs, Memory Mapped Files) - อาจใหญ่กว่า RAM จริง
- RSS: Physical RAM ที่ Process ใช้จริง (ไม่รวม Swapped Out, Shared Memory นับซ้ำได้)
- PSS (Proportional Set Size): RSS ที่แบ่งน้ำหนัก Shared Memory (อ่านจาก
/proc/<pid>/smaps)
ทางเลือกอื่น
getrusage(RUSAGE_SELF, &usage)- POSIX Standard (ให้ maxrss ใน KB)/proc/self/status- Parse ง่ายกว่า (Key: Value Format)mallinfo()/malloc_info()- Heap Allocator Stats (Glibc)
ตัวอย่างด้วย /proc/self/status (ง่ายกว่า)
void get_mem_simple(double& vm_kb, double& rss_kb) {
std::ifstream status("/proc/self/status");
std::string line;
while (std::getline(status, line)) {
if (line.rfind("VmSize:", 0) == 0)
vm_kb = std::stod(line.substr(7));
else if (line.rfind("VmRSS:", 0) == 0)
rss_kb = std::stod(line.substr(6));
}
}
สรุป
การอ่าน /proc/self/stat ให้ Low-level Control สูงสุด แต่ Parse ยุ่งยาก /proc/self/status ใช้ง่ายกว่า getrusage() เป็น Portable POSIX เลือกตามความต้องการ