Кроссплатформенный способ узнать примерное количество RAM памяти
Собственно, пока в голову пришел немного топорный метод:
BYTE GetAvailableMemory(){
llu MaxMemory = Settings::defaultmemory; // Gb
std::vector<BYTE> tester;
while (true){
try {
tester.resize(MaxMemory*1073741824);
} catch (std::bad_alloc& e) {
tester.clear();
MaxMemory--;
return ((MaxMemory) >= Settings::defaultmemory) ? MaxMemory : 0;
}
MaxMemory++;
}
return 0;
}
Данный метод работает на системе с 16 GB оперативки,
НО! Первое - он не работает (хз почему) на 32 битных системах, т.к. уже на выделении 2Gb вектора улетает в ошибку
Второе - этот метод выполняется около 12 секунд, что тоже долго.
Собственно мой вопрос - можно ли как-то оптимизировать этот топорный подсчитыватель памяти и будет ли он также работать на линукс и маке, как на винде (не положит ли он систему)?
Ответы (2 шт):
Для windows корректнее будет следующий способ
#include <Windows.h>
typedef unsigned long long uint64_t;
uint64_t GetAvailableMemory() {
typedef BOOL(WINAPI* PGMSE)(LPMEMORYSTATUSEX);
PGMSE pGMSE = (PGMSE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
if (pGMSE != 0)
{
MEMORYSTATUSEX mi;
memset(&mi, 0, sizeof(MEMORYSTATUSEX));
mi.dwLength = sizeof(MEMORYSTATUSEX);
if (pGMSE(&mi) == TRUE)
return mi.ullAvailPhys;
else
pGMSE = 0;
}
if (pGMSE == 0)
{
MEMORYSTATUS mi;
memset(&mi, 0, sizeof(MEMORYSTATUS));
mi.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&mi);
return mi.dwAvailPhys;
}
return 0; // или киньте исключение
}
Для Linux нужно будет смотреть в сторону /proc/meminfo Вот пример чтения MemFree
#include <fstream>
unsigned long get_mem_total() {
std::string token;
std::ifstream file("/proc/meminfo");
while (file >> token) {
if (token == "MemAvailable:") {
unsigned long mem;
if (file >> mem) {
return mem;
}
else {
return 0;
}
}
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return 0; // можете кинуть исключение
}
В любом случае делать это придётся препроцессорами
Вариант для Linux: использовать функцию sysinfo
// get_info.cxx
#include <sys/sysinfo.h>
#include <iostream>
int main(int argc, const char** argv) {
struct sysinfo info{};
if (0 == sysinfo(&info))
{
std::cout << "info.freeram : " << info.freeram << std::endl;
std::cout << "info.totalram : " << info.totalram << std::endl;
}
else
{
std::cerr << "call sysinfo fail" << std::endl;
}
return 0;
}
сборка:
g++ get_info.cxx -o get_info
вывод на моей системе(Debian/testing)
$> free
total used free shared buff/cache available
Mem: 16399300 7191280 428588 166348 8779432 8751060
Swap: 8375292 4352 8370940
$> ./build/get_info
info.freeram : 431308800
info.totalram : 16792883200