Memory usage is now shown in SysInfoDialog on all three platforms
This commit is contained in:
parent
ef0e323d1b
commit
b0d4cb6e06
3 changed files with 74 additions and 78 deletions
|
@ -18,8 +18,9 @@ extern void trace(unsigned int level, const char *message);
|
|||
// Format memory allocated, separate thousands by comma.
|
||||
extern std::string format_memsize_MB(size_t n);
|
||||
// Return string to be added to the boost::log output to inform about the current process memory allocation.
|
||||
// The string is non-empty only if the loglevel >= info (3).
|
||||
extern std::string log_memory_info();
|
||||
// The string is non-empty if the loglevel >= info (3) or ignore_loglevel==true.
|
||||
// Latter is used to get the memory info from SysInfoDialog.
|
||||
extern std::string log_memory_info(bool ignore_loglevel = false);
|
||||
extern void disable_multi_threading();
|
||||
// Returns the size of physical memory (RAM) in bytes.
|
||||
extern size_t total_physical_memory();
|
||||
|
|
|
@ -435,84 +435,81 @@ std::string format_memsize_MB(size_t n)
|
|||
return out + "MB";
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef PROCESS_MEMORY_COUNTERS_EX
|
||||
// MingW32 doesn't have this struct in psapi.h
|
||||
typedef struct _PROCESS_MEMORY_COUNTERS_EX {
|
||||
DWORD cb;
|
||||
DWORD PageFaultCount;
|
||||
SIZE_T PeakWorkingSetSize;
|
||||
SIZE_T WorkingSetSize;
|
||||
SIZE_T QuotaPeakPagedPoolUsage;
|
||||
SIZE_T QuotaPagedPoolUsage;
|
||||
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
SIZE_T QuotaNonPagedPoolUsage;
|
||||
SIZE_T PagefileUsage;
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivateUsage;
|
||||
} PROCESS_MEMORY_COUNTERS_EX, *PPROCESS_MEMORY_COUNTERS_EX;
|
||||
#endif /* PROCESS_MEMORY_COUNTERS_EX */
|
||||
|
||||
std::string log_memory_info()
|
||||
// Returns platform-specific string to be used as log output or parsed in SysInfoDialog.
|
||||
// The latter parses the string with (semi)colons as separators, it should look about as
|
||||
// "desc1: value1; desc2: value2" or similar (spaces should not matter).
|
||||
std::string log_memory_info(bool ignore_loglevel)
|
||||
{
|
||||
std::string out;
|
||||
if (logSeverity <= boost::log::trivial::info) {
|
||||
if (ignore_loglevel || logSeverity <= boost::log::trivial::info) {
|
||||
#ifdef WIN32
|
||||
#ifndef PROCESS_MEMORY_COUNTERS_EX
|
||||
// MingW32 doesn't have this struct in psapi.h
|
||||
typedef struct _PROCESS_MEMORY_COUNTERS_EX {
|
||||
DWORD cb;
|
||||
DWORD PageFaultCount;
|
||||
SIZE_T PeakWorkingSetSize;
|
||||
SIZE_T WorkingSetSize;
|
||||
SIZE_T QuotaPeakPagedPoolUsage;
|
||||
SIZE_T QuotaPagedPoolUsage;
|
||||
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
SIZE_T QuotaNonPagedPoolUsage;
|
||||
SIZE_T PagefileUsage;
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivateUsage;
|
||||
} PROCESS_MEMORY_COUNTERS_EX, *PPROCESS_MEMORY_COUNTERS_EX;
|
||||
#endif /* PROCESS_MEMORY_COUNTERS_EX */
|
||||
|
||||
|
||||
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
|
||||
if (hProcess != nullptr) {
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
|
||||
out = " WorkingSet: " + format_memsize_MB(pmc.WorkingSetSize) + " PrivateBytes: " + format_memsize_MB(pmc.PrivateUsage) + " Pagefile(peak): " + format_memsize_MB(pmc.PagefileUsage) + "(" + format_memsize_MB(pmc.PeakPagefileUsage) + ")";
|
||||
out = " WorkingSet: " + format_memsize_MB(pmc.WorkingSetSize) + "; PrivateBytes: " + format_memsize_MB(pmc.PrivateUsage) + "; Pagefile(peak): " + format_memsize_MB(pmc.PagefileUsage) + "(" + format_memsize_MB(pmc.PeakPagefileUsage) + ")";
|
||||
else
|
||||
out += " Used memory: N/A";
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#elif defined(__linux__) or defined(__APPLE__)
|
||||
std::string log_memory_info()
|
||||
{
|
||||
std::string out = " Unable to get current memory usage.";
|
||||
|
||||
// Get current memory usage.
|
||||
#ifdef __APPLE__
|
||||
struct mach_task_basic_info info;
|
||||
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) == KERN_SUCCESS )
|
||||
out = " Memory usage: resident: " + format_memsize_MB((size_t)info.resident_size);
|
||||
#else // i.e. __linux__
|
||||
|
||||
size_t tSize = 0, resident = 0, share = 0;
|
||||
std::ifstream buffer("/proc/self/statm");
|
||||
if (buffer) {
|
||||
if ((buffer >> tSize >> resident >> share)) {
|
||||
// Get current memory usage.
|
||||
#ifdef __APPLE__
|
||||
struct mach_task_basic_info info;
|
||||
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
out += " Resident memory: ";
|
||||
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) == KERN_SUCCESS )
|
||||
out += format_memsize_MB((size_t)info.resident_size);
|
||||
else
|
||||
out += "N/A";
|
||||
#else // i.e. __linux__
|
||||
size_t tSize = 0, resident = 0, share = 0;
|
||||
std::ifstream buffer("/proc/self/statm");
|
||||
if (buffer && (buffer >> tSize >> resident >> share)) {
|
||||
size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE); // in case x86-64 is configured to use 2MB pages
|
||||
size_t rss = resident * page_size;
|
||||
out = " Memory usage: resident: " + format_memsize_MB(rss);
|
||||
out += " shared: " + format_memsize_MB(share * page_size);
|
||||
out += " private: " + format_memsize_MB(rss - share * page_size);
|
||||
out += " Resident memory: " + format_memsize_MB(rss);
|
||||
out += "; Shared memory: " + format_memsize_MB(share * page_size);
|
||||
out += "; Private memory: " + format_memsize_MB(rss - share * page_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
out += " Used memory: N/A";
|
||||
#endif
|
||||
// Now get peak memory usage.
|
||||
out += "; Peak memory usage: ";
|
||||
rusage memory_info;
|
||||
if (getrusage(RUSAGE_SELF, &memory_info) == 0)
|
||||
{
|
||||
size_t peak_mem_usage = (size_t)memory_info.ru_maxrss;
|
||||
#ifdef __linux__
|
||||
peak_mem_usage *= 1024;// getrusage returns the value in kB on linux
|
||||
#endif
|
||||
out += format_memsize_MB(peak_mem_usage);
|
||||
}
|
||||
else
|
||||
out += "N/A";
|
||||
#endif
|
||||
// Now get peak memory usage.
|
||||
rusage memory_info;
|
||||
if (getrusage(RUSAGE_SELF, &memory_info) != 0)
|
||||
out += " Could not get peak memory usage.";
|
||||
else {
|
||||
size_t peak_mem_usage = (size_t)memory_info.ru_maxrss;
|
||||
#ifdef __linux
|
||||
peak_mem_usage *= 1024L;// getrusage returns the value in kB on linux
|
||||
#endif
|
||||
out += " Peak Memory Usage: " + format_memsize_MB(peak_mem_usage);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
#else
|
||||
std::string log_memory_info()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Returns the size of physical memory (RAM) in bytes.
|
||||
// http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
|
||||
|
|
|
@ -58,21 +58,19 @@ std::string get_mem_info(bool format_as_html)
|
|||
std::string b_end = format_as_html ? "</b>" : "";
|
||||
std::string line_end = format_as_html ? "<br>" : "\n";
|
||||
|
||||
const Slic3r::UndoRedo::Stack &stack = wxGetApp().plater()->undo_redo_stack_main();
|
||||
out << b_start << "RAM size reserved for the Undo / Redo stack [MB]: " << b_end << Slic3r::format_memsize_MB(stack.get_memory_limit()) << line_end;
|
||||
out << b_start << "RAM size occupied by the Undo / Redo stack [MB]: " << b_end << Slic3r::format_memsize_MB(stack.memsize()) << line_end << line_end;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
|
||||
if (hProcess != nullptr) {
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
|
||||
out << b_start << "WorkingSet [MB]: " << b_end << format_memsize_MB(pmc.WorkingSetSize) << line_end
|
||||
<< b_start << "PrivateBytes [MB]: " << b_end << format_memsize_MB(pmc.PrivateUsage) << line_end
|
||||
<< b_start << "Pagefile(peak) [MB]: " << b_end << format_memsize_MB(pmc.PagefileUsage) << "(" << format_memsize_MB(pmc.PeakPagefileUsage) << ")" << line_end;
|
||||
CloseHandle(hProcess);
|
||||
std::string mem_info_str = log_memory_info(true);
|
||||
std::istringstream mem_info(mem_info_str);
|
||||
std::string value;
|
||||
while (std::getline(mem_info, value, ':')) {
|
||||
out << b_start << (value+": ") << b_end;
|
||||
std::getline(mem_info, value, ';');
|
||||
out << value << line_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Slic3r::UndoRedo::Stack &stack = wxGetApp().plater()->undo_redo_stack_main();
|
||||
out << b_start << "RAM size reserved for the Undo / Redo stack: " << b_end << Slic3r::format_memsize_MB(stack.get_memory_limit()) << line_end;
|
||||
out << b_start << "RAM size occupied by the Undo / Redo stack: " << b_end << Slic3r::format_memsize_MB(stack.memsize()) << line_end << line_end;
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue