diff --git a/base/base/CMakeLists.txt b/base/base/CMakeLists.txt index 3e6f174c6dc..de7ace7c178 100644 --- a/base/base/CMakeLists.txt +++ b/base/base/CMakeLists.txt @@ -2,6 +2,7 @@ set (SRCS argsToConfig.cpp coverage.cpp demangle.cpp + getAvailableMemoryAmount.cpp getFQDNOrHostName.cpp getMemoryAmount.cpp getPageSize.cpp diff --git a/base/base/getAvailableMemoryAmount.cpp b/base/base/getAvailableMemoryAmount.cpp new file mode 100644 index 00000000000..a7fd970c216 --- /dev/null +++ b/base/base/getAvailableMemoryAmount.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +#include +#include +#include +#if defined(BSD) +#include +#include +#endif + + +uint64_t getAvailableMemoryAmountOrZero() +{ + int64_t page_size = getPageSize(); + if (page_size <= 0) + return 0; + +#if defined(__FreeBSD__) + struct vmtotal vmt; + size_t vmt_size = sizeof(vmt); + if (sysctlbyname("vm.vmtotal", &vmt, &vmt_size, NULL, 0) < 0) + return 0; + uint64_t available_pages = vmt.t_avm; +#else + uint64_t available_pages = sysconf(_SC_AVPHYS_PAGES); +#endif + + return page_size * available_pages; +} + + +uint64_t getAvailableMemoryAmount() +{ + auto res = getAvailableMemoryAmountOrZero(); + if (!res) + throw std::runtime_error("Cannot determine available memory amount"); + return res; +} diff --git a/base/base/getAvailableMemoryAmount.h b/base/base/getAvailableMemoryAmount.h new file mode 100644 index 00000000000..44612945016 --- /dev/null +++ b/base/base/getAvailableMemoryAmount.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +/** Returns the size of currently available physical memory (RAM) in bytes. + * Returns 0 on unsupported platform or if it cannot determine the size of physical memory. + */ +uint64_t getAvailableMemoryAmountOrZero(); + +/** Throws exception if it cannot determine the size of physical memory. + */ +uint64_t getAvailableMemoryAmount(); diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index 378a76a48f6..82522068d85 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -588,8 +589,14 @@ static void sanityChecks(Server* server) if (getBlockDeviceType(dev_id) == BlockDeviceType::ROT && getBlockDeviceReadAheadBytes(dev_id) == 0) server->context()->addWarningMessage("Rotational disk with disabled readahead is in use. Performance can be degraded."); #endif - if (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGE_SIZE) < (2l << 30)) - server->context()->addWarningMessage("Available memory at server startup is too low (2GiB)."); + try + { + if (getAvailableMemoryAmount() < (2l << 30)) + server->context()->addWarningMessage("Available memory at server startup is too low (2GiB)."); + } + catch (...) + { + } if (!enoughSpaceInDirectory(data_path, 1ull << 30)) server->context()->addWarningMessage("Available disk space at server startup is too low (1GiB).");