Skip to content

Commit ae11d8f

Browse files
committed
8364248: Separate commit and reservation limit detection
Reviewed-by: stuefe, ayang
1 parent e82d7f5 commit ae11d8f

File tree

5 files changed

+69
-62
lines changed

5 files changed

+69
-62
lines changed

src/hotspot/os/posix/os_posix.cpp

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ bool os::get_host_name(char* buf, size_t buflen) {
713713
}
714714

715715
#ifndef _LP64
716-
// Helper, on 32bit, for os::has_allocatable_memory_limit
716+
// Helper, on 32bit, for os::commit_memory_limit
717717
static bool is_allocatable(size_t s) {
718718
if (s < 2 * G) {
719719
return true;
@@ -731,31 +731,19 @@ static bool is_allocatable(size_t s) {
731731
}
732732
#endif // !_LP64
733733

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

735-
bool os::has_allocatable_memory_limit(size_t* limit) {
736-
struct rlimit rlim;
737-
int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);
738-
// if there was an error when calling getrlimit, assume that there is no limitation
739-
// on virtual memory.
740-
bool result;
741-
if ((getrlimit_res != 0) || (rlim.rlim_cur == RLIM_INFINITY)) {
742-
result = false;
743-
} else {
744-
*limit = (size_t)rlim.rlim_cur;
745-
result = true;
746-
}
747739
#ifdef _LP64
748-
return result;
740+
return reserve_limit;
749741
#else
750-
// arbitrary virtual space limit for 32 bit Unices found by testing. If
751-
// getrlimit above returned a limit, bound it with this limit. Otherwise
752-
// directly use it.
753-
const size_t max_virtual_limit = 3800*M;
754-
if (result) {
755-
*limit = MIN2(*limit, max_virtual_limit);
756-
} else {
757-
*limit = max_virtual_limit;
758-
}
742+
// Arbitrary max reserve limit for 32 bit Unices found by testing.
743+
const size_t max_reserve_limit = 3800 * M;
744+
745+
// Bound the reserve limit with the arbitrary max.
746+
size_t actual_limit = MIN2(reserve_limit, max_reserve_limit);
759747

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

772-
size_t upper_limit = *limit;
760+
size_t upper_limit = actual_limit;
773761

774762
// first check a few trivial cases
775763
if (is_allocatable(upper_limit) || (upper_limit <= min_allocation_size)) {
776-
*limit = upper_limit;
764+
// The actual limit is allocatable, no need to do anything.
777765
} else if (!is_allocatable(min_allocation_size)) {
778766
// we found that not even min_allocation_size is allocatable. Return it
779767
// anyway. There is no point to search for a better value any more.
780-
*limit = min_allocation_size;
768+
actual_limit = min_allocation_size;
781769
} else {
782770
// perform the binary search.
783771
size_t lower_limit = min_allocation_size;
@@ -790,12 +778,31 @@ bool os::has_allocatable_memory_limit(size_t* limit) {
790778
upper_limit = temp_limit;
791779
}
792780
}
793-
*limit = lower_limit;
781+
actual_limit = lower_limit;
794782
}
795-
return true;
783+
784+
return actual_limit;
796785
#endif
797786
}
798787

788+
size_t os::reserve_memory_limit() {
789+
struct rlimit rlim;
790+
int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);
791+
792+
// If there was an error calling getrlimit, conservatively assume no limit.
793+
if (getrlimit_res != 0) {
794+
return SIZE_MAX;
795+
}
796+
797+
// If the current limit is not infinity, there is a limit.
798+
if (rlim.rlim_cur != RLIM_INFINITY) {
799+
return (size_t)rlim.rlim_cur;
800+
}
801+
802+
// No limit
803+
return SIZE_MAX;
804+
}
805+
799806
void* os::get_default_process_handle() {
800807
#ifdef __APPLE__
801808
// MacOS X needs to use RTLD_FIRST instead of RTLD_LAZY

src/hotspot/os/windows/os_windows.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -897,13 +897,6 @@ size_t os::rss() {
897897
return rss;
898898
}
899899

900-
bool os::has_allocatable_memory_limit(size_t* limit) {
901-
MEMORYSTATUSEX ms;
902-
ms.dwLength = sizeof(ms);
903-
GlobalMemoryStatusEx(&ms);
904-
*limit = (size_t)ms.ullAvailVirtual;
905-
return true;
906-
}
907900

908901
int os::active_processor_count() {
909902
// User has overridden the number of active processors
@@ -3303,6 +3296,18 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
33033296
return aligned_base;
33043297
}
33053298

3299+
size_t os::commit_memory_limit() {
3300+
MEMORYSTATUSEX ms;
3301+
ms.dwLength = sizeof(ms);
3302+
GlobalMemoryStatusEx(&ms);
3303+
return (size_t)ms.ullAvailVirtual;
3304+
}
3305+
3306+
size_t os::reserve_memory_limit() {
3307+
// Virtual address space cannot be limited on Windows.
3308+
return SIZE_MAX;
3309+
}
3310+
33063311
char* os::reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag, bool exec) {
33073312
// exec can be ignored
33083313
return map_or_reserve_memory_aligned(size, alignment, -1/* file_desc */, mem_tag);

src/hotspot/share/gc/z/zAddressSpaceLimit.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,14 @@
3030
#include "utilities/align.hpp"
3131
#include "utilities/ostream.hpp"
3232

33-
static size_t address_space_limit() {
34-
size_t limit = 0;
35-
36-
if (os::has_allocatable_memory_limit(&limit)) {
37-
return limit;
38-
}
39-
40-
// No limit
41-
return SIZE_MAX;
42-
}
43-
4433
size_t ZAddressSpaceLimit::heap() {
4534
// Allow the heap to occupy 50% of the address space
46-
const size_t limit = address_space_limit() / MaxVirtMemFraction;
35+
const size_t limit = os::reserve_memory_limit() / MaxVirtMemFraction;
4736
return align_up(limit, ZGranuleSize);
4837
}
4938

5039
void ZAddressSpaceLimit::print_limits() {
51-
const size_t limit = address_space_limit();
40+
const size_t limit = os::reserve_memory_limit();
5241

5342
if (limit == SIZE_MAX) {
5443
log_info_p(gc, init)("Address Space Size: unlimited");

src/hotspot/share/runtime/arguments.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,19 +1487,16 @@ jint Arguments::set_ergonomics_flags() {
14871487
}
14881488

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

15051502
// Use static initialization to get the default before parsing

src/hotspot/share/runtime/os.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,6 @@ class os: AllStatic {
340340
static jlong free_swap_space();
341341

342342
static julong physical_memory();
343-
static bool has_allocatable_memory_limit(size_t* limit);
344343
static bool is_server_class_machine();
345344
static size_t rss();
346345

@@ -449,6 +448,16 @@ class os: AllStatic {
449448
// Returns the lowest address the process is allowed to map against.
450449
static size_t vm_min_address();
451450

451+
// Returns an upper limit beyond which reserve_memory() calls are guaranteed
452+
// to fail. It is not guaranteed that reserving less memory than this will
453+
// succeed, however.
454+
static size_t reserve_memory_limit();
455+
456+
// Returns an upper limit beyond which commit_memory() calls are guaranteed
457+
// to fail. It is not guaranteed that committing less memory than this will
458+
// succeed, however.
459+
static size_t commit_memory_limit();
460+
452461
inline static size_t cds_core_region_alignment();
453462

454463
// Reserves virtual memory.

0 commit comments

Comments
 (0)