Я пишу кроссплатформенный код на C++ (Windows, Mac). Есть ли способ проверить, сколько памяти используется текущим процессом? Очень надуманный фрагмент для иллюстрации:
unsigned long m0 = GetMemoryInUse();
char *p = new char[ random_number ];
unsigned long m1 = GetMemoryInUse();
printf( "%d bytes used\n", (m1-m0) );
Конечно, (m1-m0) должно быть равно random_number, но я пытаюсь сделать это на более сложном уровне, включая возможные вызовы библиотеки, которые могут выделить память.
Не рекомендуется следующее:





Возможно Вы правы. Я просто надеялся, что что-то упустил. :) Скорее всего, у меня просто будет кастомный менеджер памяти.
вы можете использовать шаблон «пул памяти». Все объекты в вашей программе выделяют / освобождают память из этого пула, чтобы вы могли узнать, сколько памяти вы потребляете.
Вот код, который я написал, чтобы попытаться сделать это переносимым способом. Это не идеально, но я думаю, что он должен, по крайней мере, дать указание на то, как это сделать на каждой из нескольких платформ.
(P.S. Я регулярно использую OSX и Linux и знаю, что это хорошо работает. Я использую Windows реже, поэтому оговорки относятся к пункту Windows, но я думаю, что это правильно.)
#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
}
У вас есть случайный #endif в строке перед определением #elif (ЯБЛОКО).
К сожалению, это не работает. :( Чем больше я копаю, тем больше кажется, что нет хорошего способа сделать это, кроме кастомного менеджера памяти.
@pbhogan Я бы придерживался кода, зависящего от платформы, как указано выше. Приведенный выше код немного запутан, но он должен обеспечить вам хороший старт (в части Windows есть ошибка - counters! = Count, см. msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx и связанный пример).
@pbhogan Что касается специального диспетчера памяти, который не даст вам размер стека, память, зарезервированную системой, память, выделенную библиотекой, и так далее ... Это новый проект? зачем вам это?
определение Windows должно быть _WIN32, _WINDOWS по умолчанию определен только для DLL и GUI EXE, консольные приложения не получают _WINDOWS, так как он не определен заранее; ссылка msdn.com/library/b0084kay
Я использовал SIGAR API для получения всевозможной информации, связанной с системой, довольно переносимой на основных платформах. Это тоже с открытым исходным кодом (Apache). В этой относительно тривиальной, но утомительной работе действительно нет необходимости изобретать велосипед.
Проверьте mallinfo ().