8292984: Refactor internal container-related interfaces for clarity

Reviewed-by: sgehwolf, eosterlund
This commit is contained in:
Casper Norrbin 2025-10-02 13:38:41 +00:00
parent 2c7f7380ea
commit 5252262349
9 changed files with 109 additions and 104 deletions

View File

@ -665,15 +665,13 @@ int CgroupSubsystem::active_processor_count() {
* -1 for unlimited
* OSCONTAINER_ERROR for not supported
*/
jlong CgroupSubsystem::memory_limit_in_bytes() {
jlong CgroupSubsystem::memory_limit_in_bytes(julong upper_bound) {
CachingCgroupController<CgroupMemoryController>* contrl = memory_controller();
CachedMetric* memory_limit = contrl->metrics_cache();
if (!memory_limit->should_check_metric()) {
return memory_limit->value();
}
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
log_trace(os, container)("total physical memory: " JULONG_FORMAT, phys_mem);
jlong mem_limit = contrl->controller()->read_memory_limit_in_bytes(phys_mem);
jlong mem_limit = contrl->controller()->read_memory_limit_in_bytes(upper_bound);
// Update cached metric to avoid re-reading container settings too often
memory_limit->set_value(mem_limit, OSCONTAINER_CACHE_TIMEOUT);
return mem_limit;
@ -841,21 +839,16 @@ jlong CgroupController::limit_from_str(char* limit_str) {
// CgroupSubsystem implementations
jlong CgroupSubsystem::memory_and_swap_limit_in_bytes() {
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
julong host_swap = os::Linux::host_swap();
return memory_controller()->controller()->memory_and_swap_limit_in_bytes(phys_mem, host_swap);
jlong CgroupSubsystem::memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound) {
return memory_controller()->controller()->memory_and_swap_limit_in_bytes(upper_mem_bound, upper_swap_bound);
}
jlong CgroupSubsystem::memory_and_swap_usage_in_bytes() {
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
julong host_swap = os::Linux::host_swap();
return memory_controller()->controller()->memory_and_swap_usage_in_bytes(phys_mem, host_swap);
jlong CgroupSubsystem::memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) {
return memory_controller()->controller()->memory_and_swap_usage_in_bytes(upper_mem_bound, upper_swap_bound);
}
jlong CgroupSubsystem::memory_soft_limit_in_bytes() {
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
return memory_controller()->controller()->memory_soft_limit_in_bytes(phys_mem);
jlong CgroupSubsystem::memory_soft_limit_in_bytes(julong upper_bound) {
return memory_controller()->controller()->memory_soft_limit_in_bytes(upper_bound);
}
jlong CgroupSubsystem::memory_throttle_limit_in_bytes() {
@ -894,7 +887,6 @@ jlong CgroupSubsystem::cpu_usage_in_micros() {
return cpuacct_controller()->cpu_usage_in_micros();
}
void CgroupSubsystem::print_version_specific_info(outputStream* st) {
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
memory_controller()->controller()->print_version_specific_info(st, phys_mem);
void CgroupSubsystem::print_version_specific_info(outputStream* st, julong upper_mem_bound) {
memory_controller()->controller()->print_version_specific_info(st, upper_mem_bound);
}

View File

@ -233,14 +233,14 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
public:
virtual jlong read_memory_limit_in_bytes(julong upper_bound) = 0;
virtual jlong memory_usage_in_bytes() = 0;
virtual jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swap) = 0;
virtual jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swap) = 0;
virtual jlong memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound) = 0;
virtual jlong memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) = 0;
virtual jlong memory_soft_limit_in_bytes(julong upper_bound) = 0;
virtual jlong memory_throttle_limit_in_bytes() = 0;
virtual jlong memory_max_usage_in_bytes() = 0;
virtual jlong rss_usage_in_bytes() = 0;
virtual jlong cache_usage_in_bytes() = 0;
virtual void print_version_specific_info(outputStream* st, julong host_mem) = 0;
virtual void print_version_specific_info(outputStream* st, julong upper_mem_bound) = 0;
virtual bool needs_hierarchy_adjustment() = 0;
virtual bool is_read_only() = 0;
virtual const char* subsystem_path() = 0;
@ -251,7 +251,7 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
class CgroupSubsystem: public CHeapObj<mtInternal> {
public:
jlong memory_limit_in_bytes();
jlong memory_limit_in_bytes(julong upper_bound);
int active_processor_count();
virtual jlong pids_max() = 0;
@ -272,14 +272,14 @@ class CgroupSubsystem: public CHeapObj<mtInternal> {
jlong cpu_usage_in_micros();
jlong memory_usage_in_bytes();
jlong memory_and_swap_limit_in_bytes();
jlong memory_and_swap_usage_in_bytes();
jlong memory_soft_limit_in_bytes();
jlong memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound);
jlong memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound);
jlong memory_soft_limit_in_bytes(julong upper_bound);
jlong memory_throttle_limit_in_bytes();
jlong memory_max_usage_in_bytes();
jlong rss_usage_in_bytes();
jlong cache_usage_in_bytes();
void print_version_specific_info(outputStream* st);
void print_version_specific_info(outputStream* st, julong upper_mem_bound);
};
// Utility class for storing info retrieved from /proc/cgroups,

View File

@ -136,35 +136,35 @@ bool CgroupV1Controller::needs_hierarchy_adjustment() {
}
static inline
void verbose_log(julong read_mem_limit, julong host_mem) {
void verbose_log(julong read_mem_limit, julong upper_mem_bound) {
if (log_is_enabled(Debug, os, container)) {
jlong mem_limit = (jlong)read_mem_limit; // account for negative values
if (mem_limit < 0 || read_mem_limit >= host_mem) {
if (mem_limit < 0 || read_mem_limit >= upper_mem_bound) {
const char *reason;
if (mem_limit == OSCONTAINER_ERROR) {
reason = "failed";
} else if (mem_limit == -1) {
reason = "unlimited";
} else {
assert(read_mem_limit >= host_mem, "Expected read value exceeding host_mem");
assert(read_mem_limit >= upper_mem_bound, "Expected read value exceeding upper memory bound");
// Exceeding physical memory is treated as unlimited. This implementation
// caps it at host_mem since Cg v1 has no value to represent 'max'.
reason = "ignored";
}
log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value " JLONG_FORMAT,
reason, mem_limit, host_mem);
log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", upper bound is " JLONG_FORMAT,
reason, mem_limit, upper_mem_bound);
}
}
}
jlong CgroupV1MemoryController::read_memory_limit_in_bytes(julong phys_mem) {
jlong CgroupV1MemoryController::read_memory_limit_in_bytes(julong upper_bound) {
julong memlimit;
CONTAINER_READ_NUMBER_CHECKED(reader(), "/memory.limit_in_bytes", "Memory Limit", memlimit);
if (memlimit >= phys_mem) {
verbose_log(memlimit, phys_mem);
if (memlimit >= upper_bound) {
verbose_log(memlimit, upper_bound);
return (jlong)-1;
} else {
verbose_log(memlimit, phys_mem);
verbose_log(memlimit, upper_bound);
return (jlong)memlimit;
}
}
@ -181,10 +181,10 @@ jlong CgroupV1MemoryController::read_memory_limit_in_bytes(julong phys_mem) {
* * -1 if there isn't any limit in place (note: includes values which exceed a physical
* upper bound)
*/
jlong CgroupV1MemoryController::read_mem_swap(julong host_total_memsw) {
jlong CgroupV1MemoryController::read_mem_swap(julong upper_memsw_bound) {
julong memswlimit;
CONTAINER_READ_NUMBER_CHECKED(reader(), "/memory.memsw.limit_in_bytes", "Memory and Swap Limit", memswlimit);
if (memswlimit >= host_total_memsw) {
if (memswlimit >= upper_memsw_bound) {
log_trace(os, container)("Memory and Swap Limit is: Unlimited");
return (jlong)-1;
} else {
@ -192,8 +192,8 @@ jlong CgroupV1MemoryController::read_mem_swap(julong host_total_memsw) {
}
}
jlong CgroupV1MemoryController::memory_and_swap_limit_in_bytes(julong host_mem, julong host_swap) {
jlong memory_swap = read_mem_swap(host_mem + host_swap);
jlong CgroupV1MemoryController::memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound) {
jlong memory_swap = read_mem_swap(upper_mem_bound + upper_swap_bound);
if (memory_swap == -1) {
return memory_swap;
}
@ -202,7 +202,7 @@ jlong CgroupV1MemoryController::memory_and_swap_limit_in_bytes(julong host_mem,
// supported.
jlong swappiness = read_mem_swappiness();
if (swappiness == 0 || memory_swap == OSCONTAINER_ERROR) {
jlong memlimit = read_memory_limit_in_bytes(host_mem);
jlong memlimit = read_memory_limit_in_bytes(upper_mem_bound);
if (memory_swap == OSCONTAINER_ERROR) {
log_trace(os, container)("Memory and Swap Limit has been reset to " JLONG_FORMAT " because swap is not supported", memlimit);
} else {
@ -220,9 +220,9 @@ jlong memory_swap_usage_impl(CgroupController* ctrl) {
return (jlong)memory_swap_usage;
}
jlong CgroupV1MemoryController::memory_and_swap_usage_in_bytes(julong phys_mem, julong host_swap) {
jlong memory_sw_limit = memory_and_swap_limit_in_bytes(phys_mem, host_swap);
jlong memory_limit = read_memory_limit_in_bytes(phys_mem);
jlong CgroupV1MemoryController::memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) {
jlong memory_sw_limit = memory_and_swap_limit_in_bytes(upper_mem_bound, upper_swap_bound);
jlong memory_limit = read_memory_limit_in_bytes(upper_mem_bound);
if (memory_sw_limit > 0 && memory_limit > 0) {
jlong delta_swap = memory_sw_limit - memory_limit;
if (delta_swap > 0) {
@ -238,10 +238,10 @@ jlong CgroupV1MemoryController::read_mem_swappiness() {
return (jlong)swappiness;
}
jlong CgroupV1MemoryController::memory_soft_limit_in_bytes(julong phys_mem) {
jlong CgroupV1MemoryController::memory_soft_limit_in_bytes(julong upper_bound) {
julong memsoftlimit;
CONTAINER_READ_NUMBER_CHECKED(reader(), "/memory.soft_limit_in_bytes", "Memory Soft Limit", memsoftlimit);
if (memsoftlimit >= phys_mem) {
if (memsoftlimit >= upper_bound) {
log_trace(os, container)("Memory Soft Limit is: Unlimited");
return (jlong)-1;
} else {
@ -336,10 +336,10 @@ jlong CgroupV1MemoryController::kernel_memory_usage_in_bytes() {
return (jlong)kmem_usage;
}
jlong CgroupV1MemoryController::kernel_memory_limit_in_bytes(julong phys_mem) {
jlong CgroupV1MemoryController::kernel_memory_limit_in_bytes(julong upper_bound) {
julong kmem_limit;
CONTAINER_READ_NUMBER_CHECKED(reader(), "/memory.kmem.limit_in_bytes", "Kernel Memory Limit", kmem_limit);
if (kmem_limit >= phys_mem) {
if (kmem_limit >= upper_bound) {
return (jlong)-1;
}
return (jlong)kmem_limit;
@ -351,9 +351,9 @@ jlong CgroupV1MemoryController::kernel_memory_max_usage_in_bytes() {
return (jlong)kmem_max_usage;
}
void CgroupV1MemoryController::print_version_specific_info(outputStream* st, julong phys_mem) {
void CgroupV1MemoryController::print_version_specific_info(outputStream* st, julong mem_bound) {
jlong kmem_usage = kernel_memory_usage_in_bytes();
jlong kmem_limit = kernel_memory_limit_in_bytes(phys_mem);
jlong kmem_limit = kernel_memory_limit_in_bytes(mem_bound);
jlong kmem_max_usage = kernel_memory_max_usage_in_bytes();
OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_limit_in_bytes");

View File

@ -79,17 +79,17 @@ class CgroupV1MemoryController final : public CgroupMemoryController {
}
jlong read_memory_limit_in_bytes(julong upper_bound) override;
jlong memory_usage_in_bytes() override;
jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swap) override;
jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swap) override;
jlong memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound) override;
jlong memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) override;
jlong memory_soft_limit_in_bytes(julong upper_bound) override;
jlong memory_throttle_limit_in_bytes() override;
jlong memory_max_usage_in_bytes() override;
jlong rss_usage_in_bytes() override;
jlong cache_usage_in_bytes() override;
jlong kernel_memory_usage_in_bytes();
jlong kernel_memory_limit_in_bytes(julong host_mem);
jlong kernel_memory_limit_in_bytes(julong upper_bound);
jlong kernel_memory_max_usage_in_bytes();
void print_version_specific_info(outputStream* st, julong host_mem) override;
void print_version_specific_info(outputStream* st, julong upper_mem_bound) override;
bool needs_hierarchy_adjustment() override {
return reader()->needs_hierarchy_adjustment();
}
@ -101,7 +101,7 @@ class CgroupV1MemoryController final : public CgroupMemoryController {
const char* cgroup_path() override { return reader()->cgroup_path(); }
private:
jlong read_mem_swappiness();
jlong read_mem_swap(julong host_total_memsw);
jlong read_mem_swap(julong upper_memsw_bound);
public:
CgroupV1MemoryController(const CgroupV1Controller& reader)

View File

@ -181,7 +181,7 @@ jlong CgroupV2MemoryController::memory_usage_in_bytes() {
return (jlong)memusage;
}
jlong CgroupV2MemoryController::memory_soft_limit_in_bytes(julong phys_mem) {
jlong CgroupV2MemoryController::memory_soft_limit_in_bytes(julong upper_bound) {
jlong mem_soft_limit;
CONTAINER_READ_NUMBER_CHECKED_MAX(reader(), "/memory.low", "Memory Soft Limit", mem_soft_limit);
return mem_soft_limit;
@ -224,19 +224,19 @@ jlong CgroupV2MemoryController::cache_usage_in_bytes() {
// respectively. In order to properly report a cgroup v1 like
// compound value we need to sum the two values. Setting a swap limit
// without also setting a memory limit is not allowed.
jlong CgroupV2MemoryController::memory_and_swap_limit_in_bytes(julong phys_mem,
julong host_swap /* unused in cg v2 */) {
jlong CgroupV2MemoryController::memory_and_swap_limit_in_bytes(julong upper_mem_bound,
julong upper_swap_bound /* unused in cg v2 */) {
jlong swap_limit;
bool is_ok = reader()->read_number_handle_max("/memory.swap.max", &swap_limit);
if (!is_ok) {
// Some container tests rely on this trace logging to happen.
log_trace(os, container)("Swap Limit failed: %d", OSCONTAINER_ERROR);
// swap disabled at kernel level, treat it as no swap
return read_memory_limit_in_bytes(phys_mem);
return read_memory_limit_in_bytes(upper_mem_bound);
}
log_trace(os, container)("Swap Limit is: " JLONG_FORMAT, swap_limit);
if (swap_limit >= 0) {
jlong memory_limit = read_memory_limit_in_bytes(phys_mem);
jlong memory_limit = read_memory_limit_in_bytes(upper_mem_bound);
assert(memory_limit >= 0, "swap limit without memory limit?");
return memory_limit + swap_limit;
}
@ -252,7 +252,7 @@ jlong memory_swap_current_value(CgroupV2Controller* ctrl) {
return (jlong)swap_current;
}
jlong CgroupV2MemoryController::memory_and_swap_usage_in_bytes(julong host_mem, julong host_swap) {
jlong CgroupV2MemoryController::memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) {
jlong memory_usage = memory_usage_in_bytes();
if (memory_usage >= 0) {
jlong swap_current = memory_swap_current_value(reader());
@ -276,7 +276,7 @@ jlong memory_limit_value(CgroupV2Controller* ctrl) {
* memory limit in bytes or
* -1 for unlimited, OSCONTAINER_ERROR for an error
*/
jlong CgroupV2MemoryController::read_memory_limit_in_bytes(julong phys_mem) {
jlong CgroupV2MemoryController::read_memory_limit_in_bytes(julong upper_bound) {
jlong limit = memory_limit_value(reader());
if (log_is_enabled(Trace, os, container)) {
if (limit == -1) {
@ -287,18 +287,18 @@ jlong CgroupV2MemoryController::read_memory_limit_in_bytes(julong phys_mem) {
}
if (log_is_enabled(Debug, os, container)) {
julong read_limit = (julong)limit; // avoid signed/unsigned compare
if (limit < 0 || read_limit >= phys_mem) {
if (limit < 0 || read_limit >= upper_bound) {
const char* reason;
if (limit == -1) {
reason = "unlimited";
} else if (limit == OSCONTAINER_ERROR) {
reason = "failed";
} else {
assert(read_limit >= phys_mem, "Expected mem limit to exceed host memory");
assert(read_limit >= upper_bound, "Expected mem limit to exceed upper memory bound");
reason = "ignored";
}
log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value " JLONG_FORMAT,
reason, limit, phys_mem);
log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", upper bound is " JLONG_FORMAT,
reason, limit, upper_bound);
}
}
return limit;
@ -327,7 +327,7 @@ bool CgroupV2Controller::needs_hierarchy_adjustment() {
return strcmp(_cgroup_path, "/") != 0;
}
void CgroupV2MemoryController::print_version_specific_info(outputStream* st, julong phys_mem) {
void CgroupV2MemoryController::print_version_specific_info(outputStream* st, julong upper_mem_bound) {
jlong swap_current = memory_swap_current_value(reader());
jlong swap_limit = memory_swap_limit_value(reader());

View File

@ -115,15 +115,15 @@ class CgroupV2MemoryController final: public CgroupMemoryController {
}
jlong read_memory_limit_in_bytes(julong upper_bound) override;
jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swp) override;
jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swp) override;
jlong memory_and_swap_limit_in_bytes(julong upper_mem_bound, julong upper_swap_bound) override;
jlong memory_and_swap_usage_in_bytes(julong upper_mem_bound, julong upper_swap_bound) override;
jlong memory_soft_limit_in_bytes(julong upper_bound) override;
jlong memory_throttle_limit_in_bytes() override;
jlong memory_usage_in_bytes() override;
jlong memory_max_usage_in_bytes() override;
jlong rss_usage_in_bytes() override;
jlong cache_usage_in_bytes() override;
void print_version_specific_info(outputStream* st, julong host_mem) override;
void print_version_specific_info(outputStream* st, julong upper_mem_bound) override;
bool is_read_only() override {
return reader()->is_read_only();
}

View File

@ -84,8 +84,8 @@ void OSContainer::init() {
// We can be in one of two cases:
// 1.) On a physical Linux system without any limit
// 2.) On a physical Linux system with a limit enforced by other means (like systemd slice)
any_mem_cpu_limit_present = cgroup_subsystem->memory_limit_in_bytes() > 0 ||
os::Linux::active_processor_count() != cgroup_subsystem->active_processor_count();
any_mem_cpu_limit_present = memory_limit_in_bytes() > 0 ||
os::Linux::active_processor_count() != active_processor_count();
if (any_mem_cpu_limit_present) {
reason = " because either a cpu or a memory limit is present";
} else {
@ -103,24 +103,47 @@ const char * OSContainer::container_type() {
return cgroup_subsystem->container_type();
}
bool OSContainer::available_memory_in_container(julong& value) {
jlong mem_limit = memory_limit_in_bytes();
jlong mem_usage = memory_usage_in_bytes();
if (mem_limit > 0 && mem_usage <= 0) {
log_debug(os, container)("container memory usage failed: " JLONG_FORMAT, mem_usage);
}
if (mem_limit <= 0 || mem_usage <= 0) {
return false;
}
value = mem_limit > mem_usage ? static_cast<julong>(mem_limit - mem_usage) : 0;
return true;
}
jlong OSContainer::memory_limit_in_bytes() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
return cgroup_subsystem->memory_limit_in_bytes();
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
return cgroup_subsystem->memory_limit_in_bytes(phys_mem);
}
jlong OSContainer::memory_and_swap_limit_in_bytes() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
return cgroup_subsystem->memory_and_swap_limit_in_bytes();
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
julong host_swap = os::Linux::host_swap();
return cgroup_subsystem->memory_and_swap_limit_in_bytes(phys_mem, host_swap);
}
jlong OSContainer::memory_and_swap_usage_in_bytes() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
return cgroup_subsystem->memory_and_swap_usage_in_bytes();
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
julong host_swap = os::Linux::host_swap();
return cgroup_subsystem->memory_and_swap_usage_in_bytes(phys_mem, host_swap);
}
jlong OSContainer::memory_soft_limit_in_bytes() {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
return cgroup_subsystem->memory_soft_limit_in_bytes();
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
return cgroup_subsystem->memory_soft_limit_in_bytes(phys_mem);
}
jlong OSContainer::memory_throttle_limit_in_bytes() {
@ -150,7 +173,8 @@ jlong OSContainer::cache_usage_in_bytes() {
void OSContainer::print_version_specific_info(outputStream* st) {
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
cgroup_subsystem->print_version_specific_info(st);
julong phys_mem = static_cast<julong>(os::Linux::physical_memory());
cgroup_subsystem->print_version_specific_info(st, phys_mem);
}
char * OSContainer::cpu_cpuset_cpus() {

View File

@ -50,6 +50,7 @@ class OSContainer: AllStatic {
static inline bool is_containerized();
static const char * container_type();
static bool available_memory_in_container(julong& value);
static jlong memory_limit_in_bytes();
static jlong memory_and_swap_limit_in_bytes();
static jlong memory_and_swap_usage_in_bytes();

View File

@ -213,33 +213,20 @@ static bool suppress_primordial_thread_resolution = false;
// utility functions
julong os::Linux::available_memory_in_container() {
julong avail_mem = static_cast<julong>(-1L);
if (OSContainer::is_containerized()) {
jlong mem_limit = OSContainer::memory_limit_in_bytes();
jlong mem_usage;
if (mem_limit > 0 && (mem_usage = OSContainer::memory_usage_in_bytes()) < 1) {
log_debug(os, container)("container memory usage failed: " JLONG_FORMAT ", using host value", mem_usage);
}
if (mem_limit > 0 && mem_usage > 0) {
avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0;
}
}
return avail_mem;
}
bool os::available_memory(physical_memory_size_type& value) {
return Linux::available_memory(value);
}
bool os::Linux::available_memory(physical_memory_size_type& value) {
julong avail_mem = available_memory_in_container();
if (avail_mem != static_cast<julong>(-1L)) {
julong avail_mem = 0;
if (OSContainer::is_containerized() && OSContainer::available_memory_in_container(avail_mem)) {
log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem);
value = static_cast<physical_memory_size_type>(avail_mem);
return true;
}
return Linux::available_memory(value);
}
bool os::Linux::available_memory(physical_memory_size_type& value) {
julong avail_mem = static_cast<julong>(-1L);
FILE *fp = os::fopen("/proc/meminfo", "r");
if (fp != nullptr) {
char buf[80];
@ -264,24 +251,25 @@ bool os::Linux::available_memory(physical_memory_size_type& value) {
}
bool os::free_memory(physical_memory_size_type& value) {
julong free_mem = 0;
if (OSContainer::is_containerized() && OSContainer::available_memory_in_container(free_mem)) {
log_trace(os)("free container memory: " JULONG_FORMAT, free_mem);
value = static_cast<physical_memory_size_type>(free_mem);
return true;
}
return Linux::free_memory(value);
}
bool os::Linux::free_memory(physical_memory_size_type& value) {
// values in struct sysinfo are "unsigned long"
struct sysinfo si;
julong free_mem = available_memory_in_container();
if (free_mem != static_cast<julong>(-1L)) {
log_trace(os)("free container memory: " JULONG_FORMAT, free_mem);
value = static_cast<physical_memory_size_type>(free_mem);
return true;
}
int ret = sysinfo(&si);
if (ret != 0) {
return false;
}
free_mem = (julong)si.freeram * si.mem_unit;
julong free_mem = (julong)si.freeram * si.mem_unit;
log_trace(os)("free memory: " JULONG_FORMAT, free_mem);
value = static_cast<physical_memory_size_type>(free_mem);
return true;