I'm writing cross platform C++ code (Windows, Mac). Is there a way to check how much memory is in use by the current process? A very contrived snippet to illustrate:
unsigned long m0 = GetMemoryInUse();
char *p = new char[ random_number ];
unsigned long m1 = GetMemoryInUse();
printf( "%d bytes used\n", (m1-m0) );
Of course (m1-m0) should equal random_number, but I'm trying to do this on a more complicated level, including possible library calls that could allocate memory.
The following are not preferable:
Here's some code I wrote to try to do this in a portable way. It's not perfect, but I think it should at least give a pointer to how to do this on each of several platforms.
(P.S. I use OSX and Linux regularly, and know this works well. I use Windows more rarely, so caveats apply to the Windows clause, but I think it's right.)
#ifdef __linux__
# include <sys/sysinfo.h>
#endif
#ifdef __APPLE__
# include <mach/task.h>
# include <mach/mach_init.h>
#endif
#ifdef _WINDOWS
# include <windows.h>
#else
# include <sys/resource.h>
#endif
/// The amount of memory currently being used by this process, in bytes.
/// By default, returns the full virtual arena, but if resident=true,
/// it will report just the resident set in RAM (if supported on that OS).
size_t memory_used (bool resident=false)
{
#if defined(__linux__)
// Ugh, getrusage doesn't work well on Linux. Try grabbing info
// directly from the /proc pseudo-filesystem. Reading from
// /proc/self/statm gives info on your own process, as one line of
// numbers that are: virtual mem program size, resident set size,
// shared pages, text/code, data/stack, library, dirty pages. The
// mem sizes should all be multiplied by the page size.
size_t size = 0;
FILE *file = fopen("/proc/self/statm", "r");
if (file) {
unsigned long vm = 0;
fscanf (file, "%ul", &vm); // Just need the first num: vm size
fclose (file);
size = (size_t)vm * getpagesize();
}
return size;
#elif defined(__APPLE__)
// Inspired by:
// http://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
size_t size = (resident ? t_info.resident_size : t_info.virtual_size);
return size;
#elif defined(_WINDOWS)
// According to MSDN...
PROCESS_MEMORY_COUNTERS counters;
if (GetProcessMemoryInfo (GetCurrentProcess(), &counters, sizeof (counters)))
return counters.PagefileUsage;
else return 0;
#else
// No idea what platform this is
return 0; // Punt
#endif
}
I've used SIGAR API to get all sorts of system related info quite portably across major platforms. It's open source (Apache) as well. There is really no need to reinvent the wheel on these relatively trivial but tedious work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With