53#if PLATFORM == PLATFORM_WINDOWS
54 PROCESS_MEMORY_COUNTERS_EX counters;
55 memset(&counters, 0,
sizeof(counters));
56 counters.cb =
sizeof(counters);
58 if (!GetProcessMemoryInfo(GetCurrentProcess(),
reinterpret_cast<PROCESS_MEMORY_COUNTERS*
>(&counters),
sizeof(counters)))
61 usage.residentBytes =
static_cast<uint64>(counters.WorkingSetSize);
62 usage.peakResidentBytes =
static_cast<uint64>(counters.PeakWorkingSetSize);
63 usage.privateBytes =
static_cast<uint64>(counters.PrivateUsage);
64 usage.hasResidentBytes =
true;
65 usage.hasPeakResidentBytes =
true;
66 usage.hasPrivateBytes =
true;
68#elif PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE
69 bool hasAnyValue =
false;
71#if PLATFORM == PLATFORM_UNIX
72 std::ifstream statm(
"/proc/self/statm");
76 if (statm >> virtualPages >> residentPages)
78 long pageSize = sysconf(_SC_PAGESIZE);
81 usage.virtualBytes = virtualPages *
static_cast<uint64>(pageSize);
82 usage.residentBytes = residentPages *
static_cast<uint64>(pageSize);
83 usage.hasVirtualBytes =
true;
84 usage.hasResidentBytes =
true;
90 struct rusage resourceUsage;
91 if (getrusage(RUSAGE_SELF, &resourceUsage) == 0)
93#if PLATFORM == PLATFORM_APPLE
94 usage.peakResidentBytes =
static_cast<uint64>(resourceUsage.ru_maxrss);
96 usage.peakResidentBytes =
static_cast<uint64>(resourceUsage.ru_maxrss) * 1024;
98 usage.hasPeakResidentBytes =
true;
112#if PLATFORM == PLATFORM_WINDOWS
113 MEMORYSTATUSEX memoryStatus;
114 memoryStatus.dwLength =
sizeof(memoryStatus);
116 if (!GlobalMemoryStatusEx(&memoryStatus))
119 usage.totalPhysicalBytes = memoryStatus.ullTotalPhys;
120 usage.availablePhysicalBytes = memoryStatus.ullAvailPhys;
121 usage.usedPhysicalBytes = memoryStatus.ullTotalPhys - memoryStatus.ullAvailPhys;
122 usage.totalVirtualBytes = memoryStatus.ullTotalPageFile;
123 usage.usedVirtualBytes = memoryStatus.ullTotalPageFile - memoryStatus.ullAvailPageFile;
124 usage.totalSwapBytes = 0;
125 usage.usedSwapBytes = 0;
127 if (
usage.totalPhysicalBytes > 0)
129 usage.physicalUsagePercent = (
static_cast<double>(
usage.usedPhysicalBytes) /
130 static_cast<double>(
usage.totalPhysicalBytes)) * 100.0;
133 if (
usage.totalVirtualBytes > 0)
135 usage.virtualUsagePercent = (
static_cast<double>(
usage.usedVirtualBytes) /
136 static_cast<double>(
usage.totalVirtualBytes)) * 100.0;
139 usage.hasValidData =
true;
142#elif PLATFORM == PLATFORM_UNIX
143 std::ifstream meminfo(
"/proc/meminfo");
144 if (!meminfo.is_open())
150 uint64 memTotal = 0, memAvailable = 0, swapTotal = 0, swapFree = 0;
152 while (meminfo >> key >> value >> unit)
154 if (key ==
"MemTotal:")
155 memTotal = value * 1024;
156 else if (key ==
"MemAvailable:")
157 memAvailable = value * 1024;
158 else if (key ==
"SwapTotal:")
159 swapTotal = value * 1024;
160 else if (key ==
"SwapFree:")
161 swapFree = value * 1024;
167 usage.totalPhysicalBytes = memTotal;
168 usage.availablePhysicalBytes = memAvailable > 0 ? memAvailable : 0;
169 usage.usedPhysicalBytes = memTotal - (memAvailable > 0 ? memAvailable : 0);
170 usage.totalSwapBytes = swapTotal;
171 usage.usedSwapBytes = swapTotal - swapFree;
172 usage.totalVirtualBytes = memTotal + swapTotal;
173 usage.usedVirtualBytes =
usage.usedPhysicalBytes +
usage.usedSwapBytes;
175 if (
usage.totalPhysicalBytes > 0)
177 usage.physicalUsagePercent = (
static_cast<double>(
usage.usedPhysicalBytes) /
178 static_cast<double>(
usage.totalPhysicalBytes)) * 100.0;
181 if (
usage.totalVirtualBytes > 0)
183 usage.virtualUsagePercent = (
static_cast<double>(
usage.usedVirtualBytes) /
184 static_cast<double>(
usage.totalVirtualBytes)) * 100.0;
187 usage.hasValidData =
true;
190#elif PLATFORM == PLATFORM_APPLE
196 length =
sizeof(uint64_t);
197 if (sysctl(mib, 2, &
usage.totalPhysicalBytes, &length,
nullptr, 0) != 0)
200 vm_statistics64_data_t vmStats;
201 mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
202 kern_return_t kernReturn = host_statistics64(mach_host_self(),
204 reinterpret_cast<host_info_t
>(&vmStats),
207 if (kernReturn != KERN_SUCCESS)
212 mib[1] = HW_PAGESIZE;
213 length =
sizeof(int);
214 if (sysctl(mib, 2, &pageSize, &length,
nullptr, 0) != 0)
217 uint64 usedMemory =
static_cast<uint64>(vmStats.active_count +
219 vmStats.compressor_page_count) * pageSize;
220 uint64 availableMemory =
static_cast<uint64>(vmStats.free_count +
221 vmStats.inactive_count +
222 vmStats.speculative_count) * pageSize;
224 usage.usedPhysicalBytes = usedMemory;
225 usage.availablePhysicalBytes = availableMemory;
227 struct xsw_usage swapUsage;
229 mib[1] = VM_SWAPUSAGE;
230 length =
sizeof(swapUsage);
231 if (sysctl(mib, 2, &swapUsage, &length,
nullptr, 0) == 0)
233 usage.totalSwapBytes = swapUsage.xsu_total;
234 usage.usedSwapBytes = swapUsage.xsu_used;
238 usage.totalSwapBytes = 0;
239 usage.usedSwapBytes = 0;
242 usage.totalVirtualBytes =
usage.totalPhysicalBytes +
usage.totalSwapBytes;
243 usage.usedVirtualBytes =
usage.usedPhysicalBytes +
usage.usedSwapBytes;
245 if (
usage.totalPhysicalBytes > 0)
247 usage.physicalUsagePercent = (
static_cast<double>(
usage.usedPhysicalBytes) /
248 static_cast<double>(
usage.totalPhysicalBytes)) * 100.0;
251 if (
usage.totalVirtualBytes > 0)
253 usage.virtualUsagePercent = (
static_cast<double>(
usage.usedVirtualBytes) /
254 static_cast<double>(
usage.totalVirtualBytes)) * 100.0;
257 usage.hasValidData =
true;
288 std::vector<std::string> fields;
290 if (
usage.hasResidentBytes)
291 AppendMemoryField(fields,
"RSS",
usage.residentBytes);
293 if (
usage.hasPrivateBytes)
294 AppendMemoryField(fields,
"Private",
usage.privateBytes);
296 if (
usage.hasVirtualBytes)
297 AppendMemoryField(fields,
"Virtual",
usage.virtualBytes);
299 if (
usage.hasPeakResidentBytes)
300 AppendMemoryField(fields,
"Peak RSS",
usage.peakResidentBytes);
303 return "unavailable";
305 std::ostringstream stream;
306 for (
size_t i = 0; i < fields.size(); ++i)
319 if (!
usage.hasValidData)
320 return "System memory info unavailable";
322 std::vector<std::string> fields;
324 AppendMemoryField(fields,
"Total RAM",
usage.totalPhysicalBytes);
325 AppendMemoryField(fields,
"Used RAM",
usage.usedPhysicalBytes);
326 AppendMemoryField(fields,
"Available RAM",
usage.availablePhysicalBytes);
327 AppendPercentageField(fields,
"RAM Usage",
usage.physicalUsagePercent);
329 if (
usage.totalSwapBytes > 0)
331 AppendMemoryField(fields,
"Total Swap",
usage.totalSwapBytes);
332 AppendMemoryField(fields,
"Used Swap",
usage.usedSwapBytes);
335 if (
usage.totalVirtualBytes > 0)
337 AppendMemoryField(fields,
"Total Virtual",
usage.totalVirtualBytes);
338 AppendMemoryField(fields,
"Used Virtual",
usage.usedVirtualBytes);
339 AppendPercentageField(fields,
"Virtual Usage",
usage.virtualUsagePercent);
342 std::ostringstream stream;
343 for (
size_t i = 0; i < fields.size(); ++i)
void usage(const char *prog)
Print out the usage string for this program on the console.