Cross-platform way to find out the approximate amount of RAM
Actually, so far, a little clumsy method has come to mind:
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;
}
This method works on a system with 16 GB of RAM,
BUT! First - it does not work (xs why) on 32-bit systems, because already on the allocation of 2Gb of the vector, it flies into an error
Second , this method runs for about 12 seconds, which is also a long time.
Actually, my question is whether it is possible to somehow optimize this clumsy memory counter and whether it will also work on Linux and mac, as on Windows (not will it put the system down)?
2 answers
For windows, the following method is more correct
#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; // или киньте исключение
}
For Linux, you will need to look in the direction of /proc/meminfo Here is an example of reading 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; // можете кинуть исключение
}
In any case, this will have to be done by preprocessors
Option for Linux: use the function 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;
}
Build:
g++ get_info.cxx -o get_info
Output on my system (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