2222 */
2323
2424#include " gc/shared/gcLogPrecious.hpp"
25+ #include " gc/z/zAdaptiveHeap.inline.hpp"
2526#include " gc/z/zAddress.inline.hpp"
2627#include " gc/z/zArray.inline.hpp"
2728#include " gc/z/zErrno.hpp"
3536#include " hugepages.hpp"
3637#include " logging/log.hpp"
3738#include " os_linux.hpp"
39+ #include " runtime/globals.hpp"
40+ #include " runtime/globals_extension.hpp"
3841#include " runtime/init.hpp"
3942#include " runtime/os.hpp"
4043#include " runtime/safefetch.hpp"
@@ -116,6 +119,8 @@ static const char* ZPreferredHugetlbfsMountpoints[] = {
116119static int z_fallocate_hugetlbfs_attempts = 3 ;
117120static bool z_fallocate_supported = true ;
118121
122+ static size_t z_max_map_count = 0 ;
123+
119124ZPhysicalMemoryBacking::ZPhysicalMemoryBacking (size_t max_capacity)
120125 : _fd(-1 ),
121126 _filesystem(0 ),
@@ -151,6 +156,14 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity)
151156 _block_size = buf.f_bsize ;
152157 _available = buf.f_bavail * _block_size;
153158
159+ // Note that the available space on a tmpfs or a hugetlbfs filesystem
160+ // will be zero if no size limit was specified when it was mounted.
161+ if (_available == 0 ) {
162+ log_info_p (gc, init)(" Available space on backing filesystem: N/A" );
163+ } else {
164+ log_info_p (gc, init)(" Available space on backing filesystem: %zuM" , _available / M);
165+ }
166+
154167 log_info_p (gc, init)(" Heap Backing Filesystem: %s (" UINT64_FORMAT_X " )" ,
155168 is_tmpfs () ? ZFILESYSTEM_TMPFS : is_hugetlbfs () ? ZFILESYSTEM_HUGETLBFS : " other" , _filesystem);
156169
@@ -308,12 +321,9 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max_capacity) const {
308321 // will be zero if no size limit was specified when it was mounted.
309322 if (_available == 0 ) {
310323 // No size limit set, skip check
311- log_info_p (gc, init)(" Available space on backing filesystem: N/A" );
312324 return ;
313325 }
314326
315- log_info_p (gc, init)(" Available space on backing filesystem: %zuM" , _available / M);
316-
317327 // Warn if the filesystem doesn't currently have enough space available to hold
318328 // the max heap size. The max heap size will be capped if we later hit this limit
319329 // when trying to expand the heap.
@@ -328,7 +338,11 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max_capacity) const {
328338 }
329339}
330340
331- void ZPhysicalMemoryBacking::warn_max_map_count (size_t max_capacity) const {
341+ void ZPhysicalMemoryBacking::compute_max_map_count () const {
342+ if (z_max_map_count != 0 ) {
343+ return ;
344+ }
345+
332346 const char * const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
333347 FILE* const file = os::fopen (filename, " r" );
334348 if (file == nullptr ) {
@@ -337,38 +351,50 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max_capacity) const {
337351 return ;
338352 }
339353
340- size_t actual_max_map_count = 0 ;
341- const int result = fscanf (file, " %zu" , &actual_max_map_count);
354+ const int result = fscanf (file, " %zu" , &z_max_map_count);
342355 fclose (file);
343356 if (result != 1 ) {
344357 // Failed to read file, skip check
345358 log_debug_p (gc, init)(" Failed to read %s" , filename);
346359 return ;
347360 }
361+ }
362+
363+ void ZPhysicalMemoryBacking::warn_max_map_count (size_t expected_capacity, size_t max_capacity) const {
364+ // In the worst case, ZGC needs 2 mappings per granule. The reason is that if the
365+ // fragmentation is at maximum, the mappings will be interleaved between being
366+ // backed by memory vs not being backed by memory.
367+ const size_t mappings_per_granule = 2 ;
348368
349369 // The required max map count is impossible to calculate exactly since subsystems
350370 // other than ZGC are also creating memory mappings, and we have no control over that.
351371 // However, ZGC tends to create the most mappings and dominate the total count.
352- // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
353- // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
354- const size_t required_max_map_count = (max_capacity / ZGranuleSize) * 3 * 1.2 ;
355- if (actual_max_map_count < required_max_map_count) {
356- log_warning_p (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
357- log_warning_p (gc)(" The system limit on number of memory mappings per process might be too low for the given" );
358- log_warning_p (gc)(" max Java heap size (%zuM). Please adjust %s to allow for at" ,
359- max_capacity / M, filename);
360- log_warning_p (gc)(" least %zu mappings (current limit is %zu). Continuing execution "
361- " with the current" , required_max_map_count, actual_max_map_count);
362- log_warning_p (gc)(" limit could lead to a premature OutOfMemoryError being thrown, due to failure to map memory." );
372+ const size_t required_max_map_count = (expected_capacity / ZGranuleSize) * mappings_per_granule * 1.2 ;
373+ if (z_max_map_count >= required_max_map_count) {
374+ return ;
363375 }
376+
377+ const size_t recommended_max_map_count = (max_capacity / ZGranuleSize) * mappings_per_granule * 1.2 ;
378+
379+ const char * const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
380+ log_warning_p (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
381+ log_warning_p (gc)(" The system limit on number of memory mappings per process might be too low for the" );
382+ log_warning_p (gc)(" Java heap size (%zuM). Please adjust %s to allow for at" ,
383+ expected_capacity / M, filename);
384+ log_warning_p (gc)(" least %zu mappings (current limit is %zu). Continuing execution "
385+ " with the current" , recommended_max_map_count, z_max_map_count);
386+ log_warning_p (gc)(" limit could lead to a premature OutOfMemoryError being thrown, due to failure to map memory." );
364387}
365388
366- void ZPhysicalMemoryBacking::warn_commit_limits (size_t max_capacity) const {
389+ void ZPhysicalMemoryBacking::warn_commit_limits (size_t expected_capacity, size_t max_capacity) const {
367390 // Warn if available space is too low
368- warn_available_space (max_capacity);
391+ warn_available_space (expected_capacity);
392+
393+ // Compute max map count the first time (during bootstrapping)
394+ compute_max_map_count ();
369395
370396 // Warn if max map count is too low
371- warn_max_map_count (max_capacity);
397+ warn_max_map_count (expected_capacity, max_capacity);
372398}
373399
374400bool ZPhysicalMemoryBacking::is_tmpfs () const {
@@ -513,7 +539,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(zbacking_offset offset, size_
513539 // some point touch these segments, otherwise we can not punch hole in them.
514540 // Also note that we need to use compat mode when using transparent huge pages,
515541 // since we need to use madvise(2) on the mapping before the page is allocated.
516- if (z_fallocate_supported && !ZLargePages::is_enabled ()) {
542+ if (z_fallocate_supported && !ZLargePages::is_explicit ()) {
517543 const ZErrno err = fallocate_fill_hole_syscall (offset, length);
518544 if (!err) {
519545 // Success
@@ -615,8 +641,12 @@ bool ZPhysicalMemoryBacking::commit_inner(zbacking_offset offset, size_t length)
615641 goto retry;
616642 }
617643
644+ static Atomic<bool > warned_failed_commit{false };
645+ if (warned_failed_commit.compare_exchange (false , true ) == false ) {
646+ log_error_p (gc)(" Failed to commit memory (%s)" , err.to_string ());
647+ }
648+
618649 // Failed
619- log_error_p (gc)(" Failed to commit memory (%s)" , err.to_string ());
620650 return false ;
621651 }
622652
@@ -705,3 +735,7 @@ void ZPhysicalMemoryBacking::unmap(zaddress_unsafe addr, size_t size) const {
705735 fatal (" Failed to map memory (%s)" , err.to_string ());
706736 }
707737}
738+
739+ void ZPhysicalMemoryBacking::collapse (zaddress_unsafe addr, size_t size) const {
740+ os::Linux::madvise_collapse_transparent_huge_pages ((void *)untype (addr), size);
741+ }
0 commit comments