mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
8305770: os::Linux::available_memory() should refer MemAvailable in /proc/meminfo
Reviewed-by: stuefe, sgehwolf, rcastanedalo, dholmes
This commit is contained in:
@@ -245,6 +245,10 @@ static bool is_close_to_brk(address a) {
|
||||
return false;
|
||||
}
|
||||
|
||||
julong os::free_memory() {
|
||||
return Aix::available_memory();
|
||||
}
|
||||
|
||||
julong os::available_memory() {
|
||||
return Aix::available_memory();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -59,6 +59,7 @@ class os::Aix {
|
||||
static int _extshm;
|
||||
|
||||
static julong available_memory();
|
||||
static julong free_memory();
|
||||
static julong physical_memory() { return _physical_memory; }
|
||||
static void initialize_system_info();
|
||||
|
||||
|
||||
@@ -138,6 +138,10 @@ julong os::available_memory() {
|
||||
return Bsd::available_memory();
|
||||
}
|
||||
|
||||
julong os::free_memory() {
|
||||
return Bsd::available_memory();
|
||||
}
|
||||
|
||||
// available here means free
|
||||
julong os::Bsd::available_memory() {
|
||||
uint64_t available = physical_memory() >> 2;
|
||||
|
||||
@@ -46,6 +46,7 @@ class os::Bsd {
|
||||
static pthread_t _main_thread;
|
||||
|
||||
static julong available_memory();
|
||||
static julong free_memory();
|
||||
static julong physical_memory() { return _physical_memory; }
|
||||
static void initialize_system_info();
|
||||
|
||||
|
||||
@@ -216,15 +216,8 @@ static bool suppress_primordial_thread_resolution = false;
|
||||
|
||||
// utility functions
|
||||
|
||||
julong os::available_memory() {
|
||||
return Linux::available_memory();
|
||||
}
|
||||
|
||||
julong os::Linux::available_memory() {
|
||||
// values in struct sysinfo are "unsigned long"
|
||||
struct sysinfo si;
|
||||
julong avail_mem;
|
||||
|
||||
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;
|
||||
@@ -233,15 +226,57 @@ julong os::Linux::available_memory() {
|
||||
}
|
||||
if (mem_limit > 0 && mem_usage > 0) {
|
||||
avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0;
|
||||
log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem);
|
||||
return avail_mem;
|
||||
}
|
||||
}
|
||||
return avail_mem;
|
||||
}
|
||||
|
||||
julong os::available_memory() {
|
||||
return Linux::available_memory();
|
||||
}
|
||||
|
||||
julong os::Linux::available_memory() {
|
||||
julong avail_mem = available_memory_in_container();
|
||||
if (avail_mem != static_cast<julong>(-1L)) {
|
||||
log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem);
|
||||
return avail_mem;
|
||||
}
|
||||
|
||||
FILE *fp = os::fopen("/proc/meminfo", "r");
|
||||
if (fp != nullptr) {
|
||||
char buf[80];
|
||||
do {
|
||||
if (fscanf(fp, "MemAvailable: " JULONG_FORMAT " kB", &avail_mem) == 1) {
|
||||
avail_mem *= K;
|
||||
break;
|
||||
}
|
||||
} while (fgets(buf, sizeof(buf), fp) != nullptr);
|
||||
fclose(fp);
|
||||
}
|
||||
if (avail_mem == static_cast<julong>(-1L)) {
|
||||
avail_mem = free_memory();
|
||||
}
|
||||
log_trace(os)("available memory: " JULONG_FORMAT, avail_mem);
|
||||
return avail_mem;
|
||||
}
|
||||
|
||||
julong os::free_memory() {
|
||||
return Linux::free_memory();
|
||||
}
|
||||
|
||||
julong os::Linux::free_memory() {
|
||||
// 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);
|
||||
return free_mem;
|
||||
}
|
||||
|
||||
sysinfo(&si);
|
||||
avail_mem = (julong)si.freeram * si.mem_unit;
|
||||
log_trace(os)("available memory: " JULONG_FORMAT, avail_mem);
|
||||
return avail_mem;
|
||||
free_mem = (julong)si.freeram * si.mem_unit;
|
||||
log_trace(os)("free memory: " JULONG_FORMAT, free_mem);
|
||||
return free_mem;
|
||||
}
|
||||
|
||||
julong os::physical_memory() {
|
||||
|
||||
@@ -51,12 +51,16 @@ class os::Linux {
|
||||
|
||||
static size_t _default_large_page_size;
|
||||
|
||||
static julong available_memory_in_container();
|
||||
|
||||
protected:
|
||||
|
||||
static julong _physical_memory;
|
||||
static pthread_t _main_thread;
|
||||
|
||||
static julong available_memory();
|
||||
static julong free_memory();
|
||||
|
||||
static int active_processor_count();
|
||||
|
||||
static void initialize_system_info();
|
||||
|
||||
@@ -830,6 +830,10 @@ julong os::available_memory() {
|
||||
return win32::available_memory();
|
||||
}
|
||||
|
||||
julong os::free_memory() {
|
||||
return win32::available_memory();
|
||||
}
|
||||
|
||||
julong os::win32::available_memory() {
|
||||
// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
|
||||
// value if total memory is larger than 4GB
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -63,6 +63,7 @@ class os::win32 {
|
||||
return _processor_level;
|
||||
}
|
||||
static julong available_memory();
|
||||
static julong free_memory();
|
||||
static julong physical_memory() { return _physical_memory; }
|
||||
|
||||
// load dll from Windows system directory or Windows directory
|
||||
|
||||
@@ -1011,7 +1011,7 @@ void CompileBroker::init_compiler_threads() {
|
||||
|
||||
void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
|
||||
|
||||
julong available_memory = os::available_memory();
|
||||
julong free_memory = os::free_memory();
|
||||
// If SegmentedCodeCache is off, both values refer to the single heap (with type CodeBlobType::All).
|
||||
size_t available_cc_np = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled),
|
||||
available_cc_p = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled);
|
||||
@@ -1023,7 +1023,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
|
||||
int old_c2_count = _compilers[1]->num_compiler_threads();
|
||||
int new_c2_count = MIN4(_c2_count,
|
||||
_c2_compile_queue->size() / 2,
|
||||
(int)(available_memory / (200*M)),
|
||||
(int)(free_memory / (200*M)),
|
||||
(int)(available_cc_np / (128*K)));
|
||||
|
||||
for (int i = old_c2_count; i < new_c2_count; i++) {
|
||||
@@ -1070,8 +1070,8 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
|
||||
ThreadsListHandle tlh; // name() depends on the TLH.
|
||||
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
|
||||
stringStream msg;
|
||||
msg.print("Added compiler thread %s (available memory: %dMB, available non-profiled code cache: %dMB)",
|
||||
ct->name(), (int)(available_memory/M), (int)(available_cc_np/M));
|
||||
msg.print("Added compiler thread %s (free memory: %dMB, available non-profiled code cache: %dMB)",
|
||||
ct->name(), (int)(free_memory/M), (int)(available_cc_np/M));
|
||||
print_compiler_threads(msg);
|
||||
}
|
||||
}
|
||||
@@ -1081,7 +1081,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
|
||||
int old_c1_count = _compilers[0]->num_compiler_threads();
|
||||
int new_c1_count = MIN4(_c1_count,
|
||||
_c1_compile_queue->size() / 4,
|
||||
(int)(available_memory / (100*M)),
|
||||
(int)(free_memory / (100*M)),
|
||||
(int)(available_cc_p / (128*K)));
|
||||
|
||||
for (int i = old_c1_count; i < new_c1_count; i++) {
|
||||
@@ -1093,8 +1093,8 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
|
||||
ThreadsListHandle tlh; // name() depends on the TLH.
|
||||
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
|
||||
stringStream msg;
|
||||
msg.print("Added compiler thread %s (available memory: %dMB, available profiled code cache: %dMB)",
|
||||
ct->name(), (int)(available_memory/M), (int)(available_cc_p/M));
|
||||
msg.print("Added compiler thread %s (free memory: %dMB, available profiled code cache: %dMB)",
|
||||
ct->name(), (int)(free_memory/M), (int)(available_cc_p/M));
|
||||
print_compiler_threads(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +310,13 @@ class os: AllStatic {
|
||||
return (_processor_count != 1);
|
||||
}
|
||||
|
||||
// On some platforms there is a distinction between "available" memory and "free" memory.
|
||||
// For example, on Linux, "available" memory (`MemAvailable` in `/proc/meminfo`) is greater
|
||||
// than "free" memory (`MemFree` in `/proc/meminfo`) because Linux can free memory
|
||||
// aggressively (e.g. clear caches) so that it becomes available.
|
||||
static julong available_memory();
|
||||
static julong free_memory();
|
||||
|
||||
static julong physical_memory();
|
||||
static bool has_allocatable_memory_limit(size_t* limit);
|
||||
static bool is_server_class_machine();
|
||||
|
||||
Reference in New Issue
Block a user