17#include <sys/resource.h>
22#include <mach/mach_host.h>
24#include <malloc/malloc.h>
25#include <sys/sysctl.h>
38Logger
g_log(
"Memory");
43 std::stringstream buffer;
44 if (mem_in_kiB <
static_cast<TYPE>(1024))
45 buffer << mem_in_kiB <<
" kB";
46 else if (mem_in_kiB <
static_cast<TYPE>(100 * 1024 * 1024))
47 buffer << (mem_in_kiB /
static_cast<TYPE>(1024)) <<
" MB";
49 buffer << (mem_in_kiB /
static_cast<TYPE>(1024 * 1024)) <<
" GB";
72 ifstream stat_stream(
"/proc/self/stat", ios_base::in);
75 string pid, comm, state, ppid, pgrp, session, tty_nr;
76 string tpgid, flags, minflt, cminflt, majflt, cmajflt;
77 string utime, stime, cutime, cstime, priority, nice;
78 string O, itrealvalue, starttime;
84 stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >>
85 majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >>
88 long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
89 vm_usage =
static_cast<size_t>(vsize /
static_cast<long double>(1024.0));
90 resident_set =
static_cast<size_t>(rss * page_size_kb);
95 struct task_basic_info t_info;
96 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
99 task_info(mach_task_self(), TASK_BASIC_INFO,
reinterpret_cast<task_info_t
>(&t_info), &t_info_count)) {
104 mach_port_t port = mach_host_self();
105 host_page_size(port, &pageSize);
106 resident_set =
static_cast<size_t>(t_info.resident_size * pageSize);
107 vm_usage =
static_cast<size_t>(t_info.virtual_size * pageSize / 1024L);
111 DWORD pid = GetCurrentProcessId();
112 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
113 if (NULL == hProcess)
115 PROCESS_MEMORY_COUNTERS pmc;
116 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
117 vm_usage = pmc.PagefileUsage / 1024;
118 resident_set = pmc.WorkingSetSize / 1024;
120 CloseHandle(hProcess);
135bool read_mem_info(
size_t &sys_avail,
size_t &sys_total) {
136 std::ifstream file(
"/proc/meminfo");
141 while (getline(file, line)) {
142 std::istringstream is(line);
148 if (tag ==
"MemTotal:") {
151 }
else if (tag ==
"MemFree:") {
154 }
else if (tag ==
"Cached:") {
157 }
else if (tag ==
"Buffers:") {
162 if (values_found == 4) {
204 if (!read_mem_info(sys_avail, sys_total)) {
205 long int totPages = sysconf(_SC_PHYS_PAGES);
206 long int avPages = sysconf(_SC_AVPHYS_PAGES);
207 long int pageSize = sysconf(_SC_PAGESIZE);
217 sys_avail = totPages / 1024 * pageSize;
221 int unusedReserved = mallinfo().fordblks / 1024;
224 if (unusedReserved < 0)
228 sys_avail += unusedReserved;
233 size_t len =
sizeof(totalmem);
235 int err = sysctlbyname(
"hw.memsize", &totalmem, &len,
nullptr, 0);
238 sys_total = totalmem / 1024;
240 mach_port_t port = mach_host_self();
243 host_page_size(port, &pageSize);
246 vm_statistics vmStats;
247 mach_msg_type_number_t
count;
248 count =
sizeof(vm_statistics) /
sizeof(natural_t);
249 err = host_statistics(port, HOST_VM_INFO,
reinterpret_cast<host_info_t
>(&vmStats), &
count);
251 g_log.
warning(
"Unable to obtain memory statistics for this Mac.");
252 sys_avail = pageSize * (vmStats.free_count + vmStats.inactive_count) / 1024;
255 const size_t unusedReserved = mstats().bytes_free / 1024;
256 g_log.
debug() <<
"Mac - Adding reserved but unused memory of " << unusedReserved <<
" KB\n";
257 sys_avail += unusedReserved;
259 GlobalMemoryStatusEx(&memStatus);
260 if (memStatus.ullTotalPhys < memStatus.ullTotalVirtual) {
261 sys_avail =
static_cast<size_t>(memStatus.ullAvailPhys / 1024);
262 sys_total =
static_cast<size_t>(memStatus.ullTotalPhys / 1024);
266 sys_avail =
static_cast<size_t>(memStatus.ullAvailVirtual / 1024);
267 sys_total =
static_cast<size_t>(memStatus.ullTotalVirtual / 1024);
271 g_log.
debug() <<
"Memory: " << sys_avail <<
" (free), " << sys_total <<
" (total).\n";
283 static bool initialized(
false);
302 mallopt(M_MMAP_THRESHOLD, 8 * 4096);
304 Logger memOptLogger(
"MemoryOptions");
310 const DWORD numHeap = GetProcessHeaps(1024, hHeaps);
311 memOptLogger.
debug() <<
"Number of heaps: " << numHeap <<
"\n";
312 ULONG ulEnableLFH = 2;
313 for (DWORD i = 0; i < numHeap; i++) {
314 if (!HeapSetInformation(hHeaps[i], HeapCompatibilityInformation, &ulEnableLFH,
sizeof(ulEnableLFH))) {
315 memOptLogger.
debug() <<
"Failed to enable the LFH for heap " << i <<
"\n";
331 memStatus.dwLength =
sizeof(MEMORYSTATUSEX);
427 MEMORY_BASIC_INFORMATION info;
429 size_t unusedReserved = 0;
431 GlobalMemoryStatusEx(&memStatus);
432 DWORDLONG GB2 = memStatus.ullTotalVirtual;
436 VirtualQuery(addr, &info,
sizeof(MEMORY_BASIC_INFORMATION));
439 if (info.State == MEM_RESERVE)
440 unusedReserved += info.RegionSize;
442 addr += info.RegionSize;
443 size += info.RegionSize;
444 }
while (size < GB2);
447 unusedReserved /= 1024;
449 return unusedReserved;
466 out <<
"virtual[" << stats.
vmUsageStr() <<
"] ";
470 out <<
"available[" << stats.
availMemStr() <<
"] ";
487 PROCESS_MEMORY_COUNTERS info;
488 GetProcessMemoryInfo(GetCurrentProcess(), &info,
sizeof(info));
489 return (
size_t)info.PeakWorkingSetSize;
491#elif (defined(_AIX) || defined(__TOS__AIX__)) || \
492 (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
494 struct psinfo psinfo;
496 if ((fd = open(
"/proc/self/psinfo", O_RDONLY)) == -1)
498 if (read(fd, &psinfo,
sizeof(psinfo)) !=
sizeof(psinfo)) {
503 return (
size_t)(psinfo.pr_rssize * 1024L);
505#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
507 struct rusage rusage;
508 getrusage(RUSAGE_SELF, &rusage);
509#if defined(__APPLE__) && defined(__MACH__)
510 return static_cast<size_t>(rusage.ru_maxrss);
512 return (
size_t)(rusage.ru_maxrss * 1024L);
531 PROCESS_MEMORY_COUNTERS info;
532 GetProcessMemoryInfo(GetCurrentProcess(), &info,
sizeof(info));
533 return (
size_t)info.WorkingSetSize;
535#elif defined(__APPLE__) && defined(__MACH__)
537 struct mach_task_basic_info info;
538 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
539 if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
reinterpret_cast<task_info_t
>(&info), &infoCount) !=
541 return static_cast<size_t>(0L);
542 return static_cast<size_t>(info.resident_size);
544#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
548 if ((fp = fopen(
"/proc/self/statm",
"r")) ==
nullptr)
550 if (fscanf(fp,
"%*s%20ld", &rss) != 1) {
555 return (
size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
double value
The value of the point.
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
The Logger class is in charge of the publishing messages from the framework through various channels.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
This class is responsible for memory statistics.
std::size_t avail_memory
Available memory of system in kiB.
std::string resUsageStr() const
Returns the resident memory used by the current process.
std::string availMemStr() const
Returns the available memory of the system as a string.
static std::mutex mutexMemory
Mutex to avoid simultaneous access to memory resources.
double getFreeRatio() const
The ratio of available to total system memory as a number between 0-100.
std::string vmUsageStr() const
Returns the virtual memory usage as a string.
std::size_t reservedMem() const
Returns the reserved memory that has not been factored into the available memory calculation.
void ignoreFields(const MemoryStatsIgnore)
Set the fields to ignore.
void update()
Update the structure with current information, taking into account what is to be ignored.
std::size_t res_usage
Resident memory usage by process in kiB.
std::size_t getCurrentRSS() const
MemoryStatsIgnore ignore
What fields to ignore.
std::size_t getPeakRSS() const
std::size_t vm_usage
Virtual memory usage by process in kiB.
std::size_t totalMem() const
Returns the total memory of the system.
MemoryStats(const MemoryStatsIgnore ignore=MEMORY_STATS_IGNORE_NONE)
Constructor.
std::string totalMemStr() const
Returns the total memory of the system as a string.
std::size_t availMem() const
Returns the available memory of the system in kiB.
std::size_t residentMem() const
Returns the memory usage of the current process in kiB.
void process_mem_system(size_t &sys_avail, size_t &sys_total)
Attempts to read the system memory statistics.
std::size_t total_memory
Total physical memory of system in kiB.
std::size_t virtualMem() const
Returns the virtual memory usage of the current process in kiB.
Logger g_log("DateAndTime")
MANTID_KERNEL_DLL void initAllocatorOptions()
Initialize platform-dependent options for memory management.
template DLLExport string memToString< uint32_t >(const uint32_t)
MANTID_KERNEL_DLL std::ostream & operator<<(std::ostream &, CPUTimer &)
Convenience function to provide for easier debug printing.
void process_mem_usage(size_t &vm_usage, size_t &resident_set)
Attempts to read the system-dependent data for a process' virtual memory size and resident set size,...
template DLLExport string memToString< uint64_t >(const uint64_t)
MemoryStatsIgnore
Enmuerate the ignored memory fields.
@ MEMORY_STATS_IGNORE_SYSTEM
@ MEMORY_STATS_IGNORE_PROCESS
std::string memToString(const TYPE mem_in_kiB)
Convert a (number) for memory in kiB to a string with proper units.