Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 35 additions & 28 deletions src/hotspot/os/posix/os_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ bool os::get_host_name(char* buf, size_t buflen) {
}

#ifndef _LP64
// Helper, on 32bit, for os::has_allocatable_memory_limit
// Helper, on 32bit, for os::commit_memory_limit
static bool is_allocatable(size_t s) {
if (s < 2 * G) {
return true;
Expand All @@ -729,31 +729,19 @@ static bool is_allocatable(size_t s) {
}
#endif // !_LP64

size_t os::commit_memory_limit() {
// On POSIX systems, the amount of memory that can be commmitted is limited
// by the size of the reservable memory.
size_t reserve_limit = reserve_memory_limit();

bool os::has_allocatable_memory_limit(size_t* limit) {
struct rlimit rlim;
int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);
// if there was an error when calling getrlimit, assume that there is no limitation
// on virtual memory.
bool result;
if ((getrlimit_res != 0) || (rlim.rlim_cur == RLIM_INFINITY)) {
result = false;
} else {
*limit = (size_t)rlim.rlim_cur;
result = true;
}
#ifdef _LP64
return result;
return reserve_limit;
#else
// arbitrary virtual space limit for 32 bit Unices found by testing. If
// getrlimit above returned a limit, bound it with this limit. Otherwise
// directly use it.
const size_t max_virtual_limit = 3800*M;
if (result) {
*limit = MIN2(*limit, max_virtual_limit);
} else {
*limit = max_virtual_limit;
}
// Arbitrary max reserve limit for 32 bit Unices found by testing.
const size_t max_reserve_limit = 3800 * M;

// Bound the reserve limit with the arbitrary max.
size_t actual_limit = MIN2(reserve_limit, max_reserve_limit);

// bound by actually allocatable memory. The algorithm uses two bounds, an
// upper and a lower limit. The upper limit is the current highest amount of
Expand All @@ -767,15 +755,15 @@ bool os::has_allocatable_memory_limit(size_t* limit) {
// the minimum amount of memory we care about allocating.
const size_t min_allocation_size = M;

size_t upper_limit = *limit;
size_t upper_limit = actual_limit;

// first check a few trivial cases
if (is_allocatable(upper_limit) || (upper_limit <= min_allocation_size)) {
*limit = upper_limit;
// The actual limit is allocatable, no need to do anything.
} else if (!is_allocatable(min_allocation_size)) {
// we found that not even min_allocation_size is allocatable. Return it
// anyway. There is no point to search for a better value any more.
*limit = min_allocation_size;
actual_limit = min_allocation_size;
} else {
// perform the binary search.
size_t lower_limit = min_allocation_size;
Expand All @@ -788,12 +776,31 @@ bool os::has_allocatable_memory_limit(size_t* limit) {
upper_limit = temp_limit;
}
}
*limit = lower_limit;
actual_limit = lower_limit;
}
return true;

return actual_limit;
#endif
}

size_t os::reserve_memory_limit() {
struct rlimit rlim;
int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);

// If there was an error calling getrlimit, conservatively assume no limit.
if (getrlimit_res != 0) {
return SIZE_MAX;
}

// If the current limit is not infinity, there is a limit.
if (rlim.rlim_cur != RLIM_INFINITY) {
return (size_t)rlim.rlim_cur;
}

// No limit
return SIZE_MAX;
}

void* os::get_default_process_handle() {
#ifdef __APPLE__
// MacOS X needs to use RTLD_FIRST instead of RTLD_LAZY
Expand Down
19 changes: 12 additions & 7 deletions src/hotspot/os/windows/os_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,13 +897,6 @@ size_t os::rss() {
return rss;
}

bool os::has_allocatable_memory_limit(size_t* limit) {
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
GlobalMemoryStatusEx(&ms);
*limit = (size_t)ms.ullAvailVirtual;
return true;
}

int os::active_processor_count() {
// User has overridden the number of active processors
Expand Down Expand Up @@ -3291,6 +3284,18 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
return aligned_base;
}

size_t os::commit_memory_limit() {
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
GlobalMemoryStatusEx(&ms);
return (size_t)ms.ullAvailVirtual;
}

size_t os::reserve_memory_limit() {
// Virtual address space cannot be limited on Windows.
return SIZE_MAX;
}

char* os::reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag, bool exec) {
// exec can be ignored
return map_or_reserve_memory_aligned(size, alignment, -1/* file_desc */, mem_tag);
Expand Down
15 changes: 2 additions & 13 deletions src/hotspot/share/gc/z/zAddressSpaceLimit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,14 @@
#include "utilities/align.hpp"
#include "utilities/ostream.hpp"

static size_t address_space_limit() {
size_t limit = 0;

if (os::has_allocatable_memory_limit(&limit)) {
return limit;
}

// No limit
return SIZE_MAX;
}

size_t ZAddressSpaceLimit::heap() {
// Allow the heap to occupy 50% of the address space
const size_t limit = address_space_limit() / MaxVirtMemFraction;
const size_t limit = os::reserve_memory_limit() / MaxVirtMemFraction;
return align_up(limit, ZGranuleSize);
}

void ZAddressSpaceLimit::print_limits() {
const size_t limit = address_space_limit();
const size_t limit = os::reserve_memory_limit();

if (limit == SIZE_MAX) {
log_info_p(gc, init)("Address Space Size: unlimited");
Expand Down
23 changes: 10 additions & 13 deletions src/hotspot/share/runtime/arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1470,19 +1470,16 @@ jint Arguments::set_ergonomics_flags() {
}

size_t Arguments::limit_heap_by_allocatable_memory(size_t limit) {
size_t max_allocatable;
size_t result = limit;
if (os::has_allocatable_memory_limit(&max_allocatable)) {
// The AggressiveHeap check is a temporary workaround to avoid calling
// GCarguments::heap_virtual_to_physical_ratio() before a GC has been
// selected. This works because AggressiveHeap implies UseParallelGC
// where we know the ratio will be 1. Once the AggressiveHeap option is
// removed, this can be cleaned up.
size_t heap_virtual_to_physical_ratio = (AggressiveHeap ? 1 : GCConfig::arguments()->heap_virtual_to_physical_ratio());
size_t fraction = MaxVirtMemFraction * heap_virtual_to_physical_ratio;
result = MIN2(result, max_allocatable / fraction);
}
return result;
// The AggressiveHeap check is a temporary workaround to avoid calling
// GCarguments::heap_virtual_to_physical_ratio() before a GC has been
// selected. This works because AggressiveHeap implies UseParallelGC
// where we know the ratio will be 1. Once the AggressiveHeap option is
// removed, this can be cleaned up.
size_t heap_virtual_to_physical_ratio = (AggressiveHeap ? 1 : GCConfig::arguments()->heap_virtual_to_physical_ratio());
size_t fraction = MaxVirtMemFraction * heap_virtual_to_physical_ratio;
size_t max_allocatable = os::commit_memory_limit();

return MIN2(limit, max_allocatable / fraction);
}

// Use static initialization to get the default before parsing
Expand Down
11 changes: 10 additions & 1 deletion src/hotspot/share/runtime/os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ class os: AllStatic {
static jlong free_swap_space();

static julong physical_memory();
static bool has_allocatable_memory_limit(size_t* limit);
static bool is_server_class_machine();
static size_t rss();

Expand Down Expand Up @@ -454,6 +453,16 @@ class os: AllStatic {
// Returns the lowest address the process is allowed to map against.
static size_t vm_min_address();

// Returns an upper limit beyond which reserve_memory() calls are guaranteed
// to fail. It is not guaranteed that reserving less memory than this will
// succeed, however.
static size_t reserve_memory_limit();

// Returns an upper limit beyond which commit_memory() calls are guaranteed
// to fail. It is not guaranteed that committing less memory than this will
// succeed, however.
static size_t commit_memory_limit();

inline static size_t cds_core_region_alignment();

// Reserves virtual memory.
Expand Down