From e84d6988d4b86f2ec5554bb8044f11a71cb5a901 Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 17 Jul 2023 13:55:37 -0700 Subject: [PATCH 01/31] Add option for dedicated ergonomics profile --- src/hotspot/share/gc/shared/gc_globals.hpp | 6 ++++ src/hotspot/share/runtime/arguments.cpp | 37 ++++++++++++++++++++++ src/hotspot/share/runtime/arguments.hpp | 1 + 3 files changed, 44 insertions(+) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 1a0b1b2c2654b..5df797908e337 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -131,6 +131,12 @@ product(bool, UseShenandoahGC, false, \ "Use the Shenandoah garbage collector") \ \ + product(ccstr, ErgonomicsProfile, "shared", \ + "Ergonomics profile to use. " \ + "Options include \"shared\" for when the JVM is running " \ + "in a shared environment and \"dedicated\" for when the " \ + "JVM is running on a system with dedicated resources") \ + \ /* notice: the max range value here is INT_MAX not UINT_MAX */ \ /* to protect from overflows */ \ product(uint, ParallelGCThreads, 0, \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 4d7975b3a5bf1..115f78df439cf 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -70,6 +70,9 @@ #if INCLUDE_JFR #include "jfr/jfr.hpp" #endif +#ifdef LINUX +#include "osContainer_linux.hpp" +#endif #include @@ -1514,6 +1517,22 @@ jint Arguments::set_ergonomics_flags() { return JNI_OK; } +void Arguments::set_ergonomics_profile() { + if (FLAG_IS_DEFAULT(ErgonomicsProfile)){ + +#ifdef LINUX + if (OSContainer::is_containerized()){ + FLAG_SET_ERGO(ErgonomicsProfile, "dedicated"); + } +#endif //LINUX + + } else { + if (strcmp(ErgonomicsProfile, "shared") != 0 && strcmp(ErgonomicsProfile, "dedicated") != 0) { + vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); + } + } +} + size_t Arguments::limit_heap_by_allocatable_memory(size_t limit) { size_t max_allocatable; size_t result = limit; @@ -1561,6 +1580,22 @@ void Arguments::set_heap_size() { : (julong)MaxRAM; } + // Update default heap size for dedicated ergonomics profile + if (strcmp(ErgonomicsProfile, "dedicated") == 0) { + FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); + FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); + if (phys_mem >= 16G){ + FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); + } else if (phys_mem >= 6G){ + FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); + } else if (phys_mem >= 4G){ + FLAG_SET_DEFAULT(MaxRAMPercentage, 80.0); + } else if (phys_mem >= 0.5G){ + FLAG_SET_DEFAULT(MaxRAMPercentage, 75.0); + } else { + FLAG_SET_DEFAULT(MaxRAMPercentage, 50.0); + } + } // Convert deprecated flags if (FLAG_IS_DEFAULT(MaxRAMPercentage) && @@ -3981,6 +4016,8 @@ jint Arguments::apply_ergo() { jint result = set_ergonomics_flags(); if (result != JNI_OK) return result; + set_ergonomics_profile(); + // Set heap size based on available physical memory set_heap_size(); diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index dcc5e9e4e70f7..2d3d58be6af25 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -260,6 +260,7 @@ class Arguments : AllStatic { static bool _ClipInlining; // GC ergonomics + static void set_ergonomics_profile(); static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); From 9cea06fb3af837c7bf71affd34431d9e57489a1d Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 17 Jul 2023 14:17:01 -0700 Subject: [PATCH 02/31] change gb --- src/hotspot/share/runtime/arguments.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 115f78df439cf..f8d006061d4bc 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1584,13 +1584,13 @@ void Arguments::set_heap_size() { if (strcmp(ErgonomicsProfile, "dedicated") == 0) { FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); - if (phys_mem >= 16G){ - FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); - } else if (phys_mem >= 6G){ + if (phys_mem >= 16 * 1024*1024*1024){ // 16g + FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); + } else if (phys_mem >= 6 *1024*1024*1024){ // 6g FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); - } else if (phys_mem >= 4G){ + } else if (phys_mem >= 4 * 1024*1024*1024){ // 4g FLAG_SET_DEFAULT(MaxRAMPercentage, 80.0); - } else if (phys_mem >= 0.5G){ + } else if (phys_mem >= 0.5 * 1024*1024*1024){ // 0.5g FLAG_SET_DEFAULT(MaxRAMPercentage, 75.0); } else { FLAG_SET_DEFAULT(MaxRAMPercentage, 50.0); From f58c9cdc5c911ed1e3e2aba7744b612cdda7cf7d Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 17 Jul 2023 14:26:12 -0700 Subject: [PATCH 03/31] change gb to prevent overflow --- src/hotspot/share/runtime/arguments.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index f8d006061d4bc..0c592d9440fda 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1584,13 +1584,13 @@ void Arguments::set_heap_size() { if (strcmp(ErgonomicsProfile, "dedicated") == 0) { FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); - if (phys_mem >= 16 * 1024*1024*1024){ // 16g + if (phys_mem >= (julong)16 * 1024*1024*1024){ // 16g FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); - } else if (phys_mem >= 6 *1024*1024*1024){ // 6g + } else if (phys_mem >= (julong)6 *1024*1024*1024){ // 6g FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); - } else if (phys_mem >= 4 * 1024*1024*1024){ // 4g + } else if (phys_mem >= (julong)4 * 1024*1024*1024){ // 4g FLAG_SET_DEFAULT(MaxRAMPercentage, 80.0); - } else if (phys_mem >= 0.5 * 1024*1024*1024){ // 0.5g + } else if (phys_mem >= (julong)0.5 * 1024*1024*1024){ // 0.5g FLAG_SET_DEFAULT(MaxRAMPercentage, 75.0); } else { FLAG_SET_DEFAULT(MaxRAMPercentage, 50.0); From e8e032402df44e12da1884ee996d12aad937771e Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 24 Jul 2023 15:57:37 -0700 Subject: [PATCH 04/31] test G --- src/hotspot/share/runtime/arguments.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 0c592d9440fda..06e2b281a63d1 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1584,7 +1584,7 @@ void Arguments::set_heap_size() { if (strcmp(ErgonomicsProfile, "dedicated") == 0) { FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); - if (phys_mem >= (julong)16 * 1024*1024*1024){ // 16g + if (phys_mem >= (julong)16*G){ // 16g FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); } else if (phys_mem >= (julong)6 *1024*1024*1024){ // 6g FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); From b84eba2edc9b8dafefad9c65fde55ebcad71a9f4 Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 24 Jul 2023 16:18:39 -0700 Subject: [PATCH 05/31] use G --- src/hotspot/share/runtime/arguments.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 06e2b281a63d1..06a383b84141a 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1584,13 +1584,13 @@ void Arguments::set_heap_size() { if (strcmp(ErgonomicsProfile, "dedicated") == 0) { FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); - if (phys_mem >= (julong)16*G){ // 16g + if (phys_mem >= 16*G){ FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); - } else if (phys_mem >= (julong)6 *1024*1024*1024){ // 6g + } else if (phys_mem >= 6*G){ FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); - } else if (phys_mem >= (julong)4 * 1024*1024*1024){ // 4g + } else if (phys_mem >= 4*G){ FLAG_SET_DEFAULT(MaxRAMPercentage, 80.0); - } else if (phys_mem >= (julong)0.5 * 1024*1024*1024){ // 0.5g + } else if (phys_mem >= 0.5*G){ FLAG_SET_DEFAULT(MaxRAMPercentage, 75.0); } else { FLAG_SET_DEFAULT(MaxRAMPercentage, 50.0); From 765fc11c15e8e911ceafeec46c11a83933a67af5 Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Tue, 25 Jul 2023 12:36:28 -0700 Subject: [PATCH 06/31] add GC selection for dedicated ergonomics profile --- src/hotspot/share/gc/shared/gcConfig.cpp | 35 ++++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 506b368d6cf05..ad71eb242f1cc 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -96,18 +96,41 @@ void GCConfig::fail_if_non_included_gc_is_selected() { } void GCConfig::select_gc_ergonomically() { - if (os::is_server_class_machine()) { + if (strcmp(ErgonomicsProfile, "shared") == 0) { + if (os::is_server_class_machine()) { #if INCLUDE_G1GC - FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); #elif INCLUDE_PARALLELGC - FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); #elif INCLUDE_SERIALGC - FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); #endif - } else { + } else { +#if INCLUDE_SERIALGC + FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); +#endif + } + } else if (strcmp(ErgonomicsProfile, "dedicated") == 0) { + phys_mem = os::physical_memory(); + if (os::active_processor_count() <= 1) { #if INCLUDE_SERIALGC - FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); +#endif + } else if (phys_mem >= 16*G){ +#if INCLUDE_ZGC + FLAG_SET_ERGO_IF_DEFAULT(UseZGC, true); #endif + } else if (phys_mem > 2048*M){ +#if INCLUDE_G1GC + FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); +#endif + } else { +#if INCLUDE_PARALLELGC + FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); +#endif + } + } else { + ShouldNotReachHere(); } } From 0bb062ee52c1f57563095dd9d2e4f117dbac52ec Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Tue, 25 Jul 2023 12:56:58 -0700 Subject: [PATCH 07/31] fix oopsie --- src/hotspot/share/gc/shared/gcConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index ad71eb242f1cc..40ce7fb5ec95f 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -111,7 +111,7 @@ void GCConfig::select_gc_ergonomically() { #endif } } else if (strcmp(ErgonomicsProfile, "dedicated") == 0) { - phys_mem = os::physical_memory(); + julong phys_mem = os::physical_memory(); if (os::active_processor_count() <= 1) { #if INCLUDE_SERIALGC FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); From 5bc7f7e458a87e70fea10baa42e20f74a00846ae Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 15:00:07 -0700 Subject: [PATCH 08/31] wip --- src/hotspot/share/runtime/arguments.cpp | 1 + .../classes/java/lang/management/RuntimeMXBean.java | 13 +++++++++++++ .../share/classes/sun/management/RuntimeImpl.java | 4 ++++ .../share/classes/sun/management/VMManagement.java | 1 + .../classes/sun/management/VMManagementImpl.java | 7 +++++++ 5 files changed, 26 insertions(+) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 06a383b84141a..1bce197b7020d 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -370,6 +370,7 @@ void Arguments::init_system_properties() { PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(), false)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false)); PropertyList_add(&_system_properties, new SystemProperty("jdk.debug", VM_Version::jdk_debug_level(), false)); + PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); // Initialize the vm.info now, but it will need updating after argument parsing. _vm_info = new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true); diff --git a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java index 2318a660c9d4e..0a3865a19b2a7 100644 --- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java +++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java @@ -359,4 +359,17 @@ public default long getPid() { * to the system properties. */ public java.util.Map getSystemProperties(); + + /** + * Returns the selected ergonomics profile for this Java virtual machine. + * The profile will be one of the following: + *
    + *
  • shared
  • + *
  • dedicated
  • + *
+ * + * @return the name of the selected ergonomics profile + */ + public String getJvmErgonomicsProfile(); + } diff --git a/src/java.management/share/classes/sun/management/RuntimeImpl.java b/src/java.management/share/classes/sun/management/RuntimeImpl.java index c919c0eeddfa2..f13d075402af3 100644 --- a/src/java.management/share/classes/sun/management/RuntimeImpl.java +++ b/src/java.management/share/classes/sun/management/RuntimeImpl.java @@ -133,6 +133,10 @@ public Map getSystemProperties() { return map; } + public String getJvmErgonomicsProfile() { + return jvm.getErgonomicsProfile(); + } + public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); } diff --git a/src/java.management/share/classes/sun/management/VMManagement.java b/src/java.management/share/classes/sun/management/VMManagement.java index f4445f0225af3..b559c2f9cd97e 100644 --- a/src/java.management/share/classes/sun/management/VMManagement.java +++ b/src/java.management/share/classes/sun/management/VMManagement.java @@ -73,6 +73,7 @@ public interface VMManagement { public long getStartupTime(); public long getUptime(); public int getAvailableProcessors(); + public String getErgonomicsProfile(); // Compilation Subsystem public String getCompilerName(); diff --git a/src/java.management/share/classes/sun/management/VMManagementImpl.java b/src/java.management/share/classes/sun/management/VMManagementImpl.java index 4e2fc26c850f5..cfa0768b66e7c 100644 --- a/src/java.management/share/classes/sun/management/VMManagementImpl.java +++ b/src/java.management/share/classes/sun/management/VMManagementImpl.java @@ -33,6 +33,9 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; + +import org.w3c.dom.css.Counter; + import java.util.Arrays; import java.util.Collections; import java.security.AccessController; @@ -201,6 +204,10 @@ public synchronized List getVmArguments() { private native long getUptime0(); public native int getAvailableProcessors(); + public String getErgonomicsProfile() { + return System.getProperty("java.vm.ergonomics.profile"); + } + // Compilation Subsystem public String getCompilerName() { @SuppressWarnings("removal") From 08cc6cedf5d1fe9d8d9a6196d4739639c53d6589 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 22:13:44 +0000 Subject: [PATCH 09/31] Remove auto import --- .../share/classes/sun/management/VMManagementImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/java.management/share/classes/sun/management/VMManagementImpl.java b/src/java.management/share/classes/sun/management/VMManagementImpl.java index cfa0768b66e7c..b8447e7c9a7e7 100644 --- a/src/java.management/share/classes/sun/management/VMManagementImpl.java +++ b/src/java.management/share/classes/sun/management/VMManagementImpl.java @@ -34,8 +34,6 @@ import java.net.UnknownHostException; import java.util.List; -import org.w3c.dom.css.Counter; - import java.util.Arrays; import java.util.Collections; import java.security.AccessController; From b254d08c9889f825cb4321b9d92c3b595643470c Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 22:41:22 +0000 Subject: [PATCH 10/31] Real world doc for ErgonomicsProfile flag --- src/hotspot/share/gc/shared/gc_globals.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 5df797908e337..106fd5b236c3a 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -133,9 +133,9 @@ \ product(ccstr, ErgonomicsProfile, "shared", \ "Ergonomics profile to use. " \ - "Options include \"shared\" for when the JVM is running " \ - "in a shared environment and \"dedicated\" for when the " \ - "JVM is running on a system with dedicated resources") \ + "\"shared\" (default) for when the JVM is running " \ + "in a traditional environment and \"dedicated\" for when the " \ + "JVM is running on an environment such as containers") \ \ /* notice: the max range value here is INT_MAX not UINT_MAX */ \ /* to protect from overflows */ \ From b5ff7025a97b1f1c5ac1ef2e7bebd13411d40add Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 15:49:59 -0700 Subject: [PATCH 11/31] Remove leading whitespace Co-authored-by: Martijn Verburg --- src/hotspot/share/runtime/arguments.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 1bce197b7020d..41f4fa2884d49 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1581,7 +1581,7 @@ void Arguments::set_heap_size() { : (julong)MaxRAM; } - // Update default heap size for dedicated ergonomics profile + // Update default heap size for dedicated ergonomics profile if (strcmp(ErgonomicsProfile, "dedicated") == 0) { FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); From 5768a4a9a96b04348a193bbcf322da5337ad10b7 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 22:55:02 +0000 Subject: [PATCH 12/31] Validate ergonomic profile in a function --- src/hotspot/share/runtime/arguments.cpp | 15 ++++++++++++++- src/hotspot/share/runtime/arguments.hpp | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 41f4fa2884d49..3c4da4a3c92e8 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1491,6 +1491,19 @@ void Arguments::set_use_compressed_klass_ptrs() { #endif // _LP64 } +bool Arguments::is_valid_ergonomics_profile(const char* profile) { + if (profile == NULL) { + return false; + } + if (strcmp(profile, "shared") == 0) { + return true; + } + if (strcmp(profile, "dedicated") == 0) { + return true; + } + return false; +} + void Arguments::set_conservative_max_heap_alignment() { // The conservative maximum required alignment for the heap is the maximum of // the alignments imposed by several sources: any requirements from the heap @@ -1528,7 +1541,7 @@ void Arguments::set_ergonomics_profile() { #endif //LINUX } else { - if (strcmp(ErgonomicsProfile, "shared") != 0 && strcmp(ErgonomicsProfile, "dedicated") != 0) { + if (!is_valid_ergonomics_profile(ErgonomicsProfile)) { vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); } } diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 2d3d58be6af25..77476b5a1bac9 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -261,6 +261,7 @@ class Arguments : AllStatic { // GC ergonomics static void set_ergonomics_profile(); + static bool is_valid_ergonomics_profile(const char* profile); static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); From 613c117ef133d9816424e5dd1244a2bcffd335b0 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 23:26:29 +0000 Subject: [PATCH 13/31] Fix where we set the sys property --- src/hotspot/share/runtime/arguments.cpp | 21 ++++++--------------- src/hotspot/share/runtime/arguments.hpp | 1 - 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 3c4da4a3c92e8..932410d31da19 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -370,7 +370,6 @@ void Arguments::init_system_properties() { PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(), false)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false)); PropertyList_add(&_system_properties, new SystemProperty("jdk.debug", VM_Version::jdk_debug_level(), false)); - PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); // Initialize the vm.info now, but it will need updating after argument parsing. _vm_info = new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true); @@ -1491,17 +1490,10 @@ void Arguments::set_use_compressed_klass_ptrs() { #endif // _LP64 } -bool Arguments::is_valid_ergonomics_profile(const char* profile) { - if (profile == NULL) { - return false; - } - if (strcmp(profile, "shared") == 0) { - return true; - } - if (strcmp(profile, "dedicated") == 0) { - return true; +static void validate_ergonomics_profile() { + if (strcmp(ErgonomicsProfile, "shared") != 0 && strcmp(ErgonomicsProfile, "dedicated") != 0) { + vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); } - return false; } void Arguments::set_conservative_max_heap_alignment() { @@ -1532,6 +1524,9 @@ jint Arguments::set_ergonomics_flags() { } void Arguments::set_ergonomics_profile() { + validate_ergonomics_profile(); + PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); + if (FLAG_IS_DEFAULT(ErgonomicsProfile)){ #ifdef LINUX @@ -1540,10 +1535,6 @@ void Arguments::set_ergonomics_profile() { } #endif //LINUX - } else { - if (!is_valid_ergonomics_profile(ErgonomicsProfile)) { - vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); - } } } diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 77476b5a1bac9..2d3d58be6af25 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -261,7 +261,6 @@ class Arguments : AllStatic { // GC ergonomics static void set_ergonomics_profile(); - static bool is_valid_ergonomics_profile(const char* profile); static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); From 6559389928500e47bfb7369d29c765b77e88f124 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 23:34:48 +0000 Subject: [PATCH 14/31] Store after it may have been changed --- src/hotspot/share/runtime/arguments.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 932410d31da19..d3c6b83087fc1 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1525,17 +1525,16 @@ jint Arguments::set_ergonomics_flags() { void Arguments::set_ergonomics_profile() { validate_ergonomics_profile(); - PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); if (FLAG_IS_DEFAULT(ErgonomicsProfile)){ - #ifdef LINUX if (OSContainer::is_containerized()){ FLAG_SET_ERGO(ErgonomicsProfile, "dedicated"); } #endif //LINUX - } + + PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); } size_t Arguments::limit_heap_by_allocatable_memory(size_t limit) { From 93cad80405976cab97899979b1eb8f484c8e005a Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Mon, 7 Aug 2023 23:55:19 +0000 Subject: [PATCH 15/31] Set the profile before the flags --- src/hotspot/share/runtime/arguments.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index d3c6b83087fc1..75add1640d0d0 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -4016,12 +4016,13 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { } jint Arguments::apply_ergo() { + // Set the ergonomics profile + set_ergonomics_profile(); + // Set flags based on ergonomics. jint result = set_ergonomics_flags(); if (result != JNI_OK) return result; - set_ergonomics_profile(); - // Set heap size based on available physical memory set_heap_size(); From 92c1df162eb7f5ecc9af4f4fc5de7d8d9a53d6d6 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 8 Aug 2023 00:39:31 +0000 Subject: [PATCH 16/31] Minor fixes --- src/hotspot/share/gc/shared/gcConfig.cpp | 37 +++++++++++++++--------- src/hotspot/share/runtime/arguments.cpp | 1 + 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 40ce7fb5ec95f..64bd506a10967 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -95,32 +95,33 @@ void GCConfig::fail_if_non_included_gc_is_selected() { NOT_ZGC( FAIL_IF_SELECTED(UseZGC)); } -void GCConfig::select_gc_ergonomically() { - if (strcmp(ErgonomicsProfile, "shared") == 0) { - if (os::is_server_class_machine()) { +void select_gc_ergonomically_shared() { + if (os::is_server_class_machine()) { #if INCLUDE_G1GC - FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); #elif INCLUDE_PARALLELGC - FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); #elif INCLUDE_SERIALGC - FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); #endif - } else { + } else { #if INCLUDE_SERIALGC - FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); + FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); #endif - } - } else if (strcmp(ErgonomicsProfile, "dedicated") == 0) { - julong phys_mem = os::physical_memory(); - if (os::active_processor_count() <= 1) { + } +} + +void select_gc_ergonomically_dedicated() { + julong phys_mem = os::physical_memory(); + if (os::active_processor_count() <= 1) { #if INCLUDE_SERIALGC FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); #endif - } else if (phys_mem >= 16*G){ + } else if (phys_mem >= 16*G) { #if INCLUDE_ZGC FLAG_SET_ERGO_IF_DEFAULT(UseZGC, true); #endif - } else if (phys_mem > 2048*M){ + } else if (phys_mem > 2048*M) { #if INCLUDE_G1GC FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true); #endif @@ -129,7 +130,15 @@ void GCConfig::select_gc_ergonomically() { FLAG_SET_ERGO_IF_DEFAULT(UseParallelGC, true); #endif } +} + +void GCConfig::select_gc_ergonomically() { + if (strcmp(ErgonomicsProfile, "shared") == 0) { + select_gc_ergonomically_shared(); + } else if (strcmp(ErgonomicsProfile, "dedicated") == 0) { + select_gc_ergonomically_dedicated(); } else { + // We have got to have at least one GC selected. Otherwise, we will crash. ShouldNotReachHere(); } } diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 75add1640d0d0..1db63eeffa7b5 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1534,6 +1534,7 @@ void Arguments::set_ergonomics_profile() { #endif //LINUX } + // Store so we can expose through JMX RuntimeMBean PropertyList_add(&_system_properties, new SystemProperty("java.vm.ergonomics.profile", ErgonomicsProfile, false)); } From d8a19e61533e66bf2df28bd90b3af1a6c844a2be Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 8 Aug 2023 18:08:26 +0000 Subject: [PATCH 17/31] No need to change MinRAMPercentage here. MinRAMPercentage is used as maxheap by the legacy ergonomics (aka shared) for when the environment has up to 512MB of RAM. --- src/hotspot/share/runtime/arguments.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 1db63eeffa7b5..1ab43a758dd1e 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1587,7 +1587,6 @@ void Arguments::set_heap_size() { // Update default heap size for dedicated ergonomics profile if (strcmp(ErgonomicsProfile, "dedicated") == 0) { - FLAG_SET_DEFAULT(MinRAMPercentage, 25.0); FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); if (phys_mem >= 16*G){ FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); From a7c5576fc3d772028531ce99d50989bb5b7ab6aa Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 8 Aug 2023 21:19:11 +0000 Subject: [PATCH 18/31] Remove unnecessary new line --- .../share/classes/sun/management/VMManagementImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java.management/share/classes/sun/management/VMManagementImpl.java b/src/java.management/share/classes/sun/management/VMManagementImpl.java index b8447e7c9a7e7..7a5c64241f412 100644 --- a/src/java.management/share/classes/sun/management/VMManagementImpl.java +++ b/src/java.management/share/classes/sun/management/VMManagementImpl.java @@ -33,7 +33,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; - import java.util.Arrays; import java.util.Collections; import java.security.AccessController; From 6fd006952b23ab73ec8117ba2786613bc78fff1b Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 6 Oct 2023 10:47:47 +0200 Subject: [PATCH 19/31] Expose selected GC name through JMX --- src/hotspot/share/gc/shared/gcConfig.cpp | 9 +++++++++ src/hotspot/share/gc/shared/gcConfig.hpp | 2 ++ src/hotspot/share/runtime/arguments.cpp | 2 ++ .../classes/java/lang/management/RuntimeMXBean.java | 7 +++++++ .../share/classes/sun/management/RuntimeImpl.java | 4 ++++ .../share/classes/sun/management/VMManagement.java | 1 + .../share/classes/sun/management/VMManagementImpl.java | 4 ++++ 7 files changed, 29 insertions(+) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 64bd506a10967..074f25002361f 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -85,6 +85,7 @@ SHENANDOAHGC_ONLY_ARG(IncludedGC(UseShenandoahGC, CollectedHeap::Shenandoah, GCArguments* GCConfig::_arguments = nullptr; bool GCConfig::_gc_selected_ergonomically = false; +const char* GCConfig::_gc_name = nullptr; void GCConfig::fail_if_non_included_gc_is_selected() { NOT_EPSILONGC( FAIL_IF_SELECTED(UseEpsilonGC)); @@ -197,6 +198,10 @@ GCArguments* GCConfig::select_gc() { // Exactly one GC selected FOR_EACH_INCLUDED_GC(gc) { if (gc->_flag) { + _gc_name = gc->_hs_err_name; + if (ZGenerational) { + _gc_name = "z gen gc"; + } return &gc->_arguments; } } @@ -239,6 +244,10 @@ bool GCConfig::is_gc_selected_ergonomically() { return _gc_selected_ergonomically; } +const char* GCConfig::gc_name() { + return _gc_name; +} + const char* GCConfig::hs_err_name() { if (is_exactly_one_gc_selected()) { // Exactly one GC selected diff --git a/src/hotspot/share/gc/shared/gcConfig.hpp b/src/hotspot/share/gc/shared/gcConfig.hpp index 9b0da3ad528a8..c7d204dfef0ca 100644 --- a/src/hotspot/share/gc/shared/gcConfig.hpp +++ b/src/hotspot/share/gc/shared/gcConfig.hpp @@ -34,6 +34,7 @@ class GCConfig : public AllStatic { private: static GCArguments* _arguments; static bool _gc_selected_ergonomically; + static const char* _gc_name; static void fail_if_non_included_gc_is_selected(); static bool is_no_gc_selected(); @@ -53,6 +54,7 @@ class GCConfig : public AllStatic { static const char* hs_err_name(CollectedHeap::Name name); static GCArguments* arguments(); + static const char* gc_name(); }; #endif // SHARE_GC_SHARED_GCCONFIG_HPP diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index e4e27c4a5a6a4..e07a3e16e4380 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1511,6 +1511,8 @@ void Arguments::set_conservative_max_heap_alignment() { jint Arguments::set_ergonomics_flags() { GCConfig::initialize(); + // Store the name of the selected GC + PropertyList_add(&_system_properties, new SystemProperty("java.vm.gc.name", GCConfig::gc_name(), false)); set_conservative_max_heap_alignment(); diff --git a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java index 0a3865a19b2a7..e614fcbc035c3 100644 --- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java +++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java @@ -372,4 +372,11 @@ public default long getPid() { */ public String getJvmErgonomicsProfile(); + /** + * Returns the name of the active garbage collector. + * + * @return the name of the active GC in this runtime + */ + public String getGCName(); + } diff --git a/src/java.management/share/classes/sun/management/RuntimeImpl.java b/src/java.management/share/classes/sun/management/RuntimeImpl.java index f13d075402af3..9eb14c339c952 100644 --- a/src/java.management/share/classes/sun/management/RuntimeImpl.java +++ b/src/java.management/share/classes/sun/management/RuntimeImpl.java @@ -137,6 +137,10 @@ public String getJvmErgonomicsProfile() { return jvm.getErgonomicsProfile(); } + public String getGCName() { + return jvm.getGCName(); + } + public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); } diff --git a/src/java.management/share/classes/sun/management/VMManagement.java b/src/java.management/share/classes/sun/management/VMManagement.java index b559c2f9cd97e..e43895738187b 100644 --- a/src/java.management/share/classes/sun/management/VMManagement.java +++ b/src/java.management/share/classes/sun/management/VMManagement.java @@ -74,6 +74,7 @@ public interface VMManagement { public long getUptime(); public int getAvailableProcessors(); public String getErgonomicsProfile(); + public String getGCName(); // Compilation Subsystem public String getCompilerName(); diff --git a/src/java.management/share/classes/sun/management/VMManagementImpl.java b/src/java.management/share/classes/sun/management/VMManagementImpl.java index 7a5c64241f412..e0e591146191b 100644 --- a/src/java.management/share/classes/sun/management/VMManagementImpl.java +++ b/src/java.management/share/classes/sun/management/VMManagementImpl.java @@ -205,6 +205,10 @@ public String getErgonomicsProfile() { return System.getProperty("java.vm.ergonomics.profile"); } + public String getGCName() { + return System.getProperty("java.vm.gc.name"); + } + // Compilation Subsystem public String getCompilerName() { @SuppressWarnings("removal") From eafd4f4714ea232045b2bf757fa433fc7471e784 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Thu, 25 Apr 2024 10:05:47 -0700 Subject: [PATCH 20/31] use auto by default --- src/hotspot/share/gc/shared/gc_globals.hpp | 8 ++++---- src/hotspot/share/runtime/arguments.cpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index c5d102637a49f..784daa5a8524f 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -124,11 +124,11 @@ product(bool, UseShenandoahGC, false, \ "Use the Shenandoah garbage collector") \ \ - product(ccstr, ErgonomicsProfile, "shared", \ + product(ccstr, ErgonomicsProfile, "auto", \ "Ergonomics profile to use. " \ - "\"shared\" (default) for when the JVM is running " \ - "in a traditional environment and \"dedicated\" for when the " \ - "JVM is running on an environment such as containers") \ + "\"auto\" by default. " \ + "\"shared\" for traditional environments and \"dedicated\" for \ + "environments with dedicated resources for the JVM") \ \ /* notice: the max range value here is INT_MAX not UINT_MAX */ \ /* to protect from overflows */ \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 1361af41c5376..b348c15e44422 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1479,10 +1479,14 @@ jint Arguments::set_ergonomics_flags() { void Arguments::set_ergonomics_profile() { validate_ergonomics_profile(); + // Uncomment the following code to enable this feature once it has been validated by the OpenJDK community + // Set default ergonomics profile based on containerization if (FLAG_IS_DEFAULT(ErgonomicsProfile)){ #ifdef LINUX if (OSContainer::is_containerized()){ FLAG_SET_ERGO(ErgonomicsProfile, "dedicated"); + } else { + FLAG_SET_ERGO(ErgonomicsProfile, "shared"); } #endif //LINUX } From 436ba32bf370a7bd7bf0fb498693e8eb21286ca9 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Thu, 25 Apr 2024 10:06:17 -0700 Subject: [PATCH 21/31] missing qupte --- src/hotspot/share/gc/shared/gc_globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 784daa5a8524f..73c6aec5fab6b 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -127,7 +127,7 @@ product(ccstr, ErgonomicsProfile, "auto", \ "Ergonomics profile to use. " \ "\"auto\" by default. " \ - "\"shared\" for traditional environments and \"dedicated\" for \ + "\"shared\" for traditional environments and \"dedicated\" for" \ "environments with dedicated resources for the JVM") \ \ /* notice: the max range value here is INT_MAX not UINT_MAX */ \ From a0199e4008a3f26a23b4960b9228cc33dcce1a40 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Thu, 25 Apr 2024 22:23:11 -0700 Subject: [PATCH 22/31] simplified --- src/hotspot/share/gc/shared/gcConfig.cpp | 7 ++ src/hotspot/share/gc/shared/gc_globals.hpp | 9 +- src/hotspot/share/runtime/arguments.cpp | 57 ++++++----- src/hotspot/share/runtime/arguments.hpp | 2 + .../gc/ergonomics/TestErgonomicsProfiles.java | 95 +++++++++++++++++++ 5 files changed, 143 insertions(+), 27 deletions(-) create mode 100644 test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 074f25002361f..b42c6d1c1a4b3 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -112,6 +112,13 @@ void select_gc_ergonomically_shared() { } } +// Selects the garbage collector (GC) ergonomically based on the system's characteristics. +// It first checks the physical memory available on the system and the number of active processors. +// Depending on these factors, it sets the appropriate GC flag to true using the FLAG_SET_ERGO_IF_DEFAULT macro. +// If the system has only one active processor, it selects the Serial GC, no matter how much memory is available. +// If the system has more than one active processor and the physical memory is greater than or equal to 16GB, it selects the ZGC. +// If the physical memory is greater than 2GB, it selects the G1GC. +// Otherwise, it selects the Parallel GC. void select_gc_ergonomically_dedicated() { julong phys_mem = os::physical_memory(); if (os::active_processor_count() <= 1) { diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 73c6aec5fab6b..12a7348e13c7b 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -124,11 +124,12 @@ product(bool, UseShenandoahGC, false, \ "Use the Shenandoah garbage collector") \ \ - product(ccstr, ErgonomicsProfile, "auto", \ + /* notice: once stable enough, goal is to change default to auto */ \ + product(ccstr, ErgonomicsProfile, "shared", \ "Ergonomics profile to use. " \ - "\"auto\" by default. " \ - "\"shared\" for traditional environments and \"dedicated\" for" \ - "environments with dedicated resources for the JVM") \ + "\"auto\" for automatic selection. " \ + "\"shared\" for traditional environments (default). " \ + "\"dedicated\" for environments with dedicated resources.") \ \ /* notice: the max range value here is INT_MAX not UINT_MAX */ \ /* to protect from overflows */ \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index b348c15e44422..59fc5bd36c3f0 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1442,7 +1442,10 @@ void Arguments::set_use_compressed_klass_ptrs() { } static void validate_ergonomics_profile() { - if (strcmp(ErgonomicsProfile, "shared") != 0 && strcmp(ErgonomicsProfile, "dedicated") != 0) { + if ( + strcmp(ErgonomicsProfile, "shared") != 0 && + strcmp(ErgonomicsProfile, "dedicated") != 0 && + strcmp(ErgonomicsProfile, "auto") != 0){ vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); } } @@ -1479,16 +1482,18 @@ jint Arguments::set_ergonomics_flags() { void Arguments::set_ergonomics_profile() { validate_ergonomics_profile(); - // Uncomment the following code to enable this feature once it has been validated by the OpenJDK community - // Set default ergonomics profile based on containerization - if (FLAG_IS_DEFAULT(ErgonomicsProfile)){ -#ifdef LINUX + // Check if the value is 'auto'. + if (strcmp(ErgonomicsProfile, "auto") == 0) { + // Set the ergonomics profile based on platform. + // If it is a Linux environment, check if we are inside a container. + // If yes, we apply dedicated automatically. + // May support other platforms in the future (e.g. Windows Containers, Solaris Zones, FreeBSD Jails, Virtuozzo OpenVZ, etc). + #ifdef LINUX if (OSContainer::is_containerized()){ FLAG_SET_ERGO(ErgonomicsProfile, "dedicated"); - } else { + } else + #endif //LINUX FLAG_SET_ERGO(ErgonomicsProfile, "shared"); - } -#endif //LINUX } // Store so we can expose through JMX RuntimeMBean @@ -1539,21 +1544,8 @@ void Arguments::set_heap_size() { : (julong)MaxRAM; } - // Update default heap size for dedicated ergonomics profile - if (strcmp(ErgonomicsProfile, "dedicated") == 0) { - FLAG_SET_DEFAULT(InitialRAMPercentage, 50.0); - if (phys_mem >= 16*G){ - FLAG_SET_DEFAULT(MaxRAMPercentage, 90.0); - } else if (phys_mem >= 6*G){ - FLAG_SET_DEFAULT(MaxRAMPercentage, 85.0); - } else if (phys_mem >= 4*G){ - FLAG_SET_DEFAULT(MaxRAMPercentage, 80.0); - } else if (phys_mem >= 0.5*G){ - FLAG_SET_DEFAULT(MaxRAMPercentage, 75.0); - } else { - FLAG_SET_DEFAULT(MaxRAMPercentage, 50.0); - } - } + set_ergonomics_profiles_heap_size_max_ram_percentage(phys_mem); + // If the maximum heap size has not been set with -Xmx, // then set it as fraction of the size of physical memory, // respecting the maximum and minimum sizes of the heap. @@ -1661,6 +1653,25 @@ void Arguments::set_heap_size() { } } +void Arguments::set_ergonomics_profiles_heap_size_max_ram_percentage(julong phys_mem) { + // Update default heap size for dedicated ergonomics profile + if (strcmp(ErgonomicsProfile, "dedicated") == 0) { + FLAG_SET_ERGO_IF_DEFAULT(InitialRAMPercentage, 50.0); + + if (phys_mem >= 16 * G) { + FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 90.0); + } else if (phys_mem >= 6 * G) { + FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 85.0); + } else if (phys_mem >= 4 * G) { + FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 80.0); + } else if (phys_mem >= 0.5 * G) { + FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 75.0); + } else { + FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 50.0); + } + } +} + // This option inspects the machine and attempts to set various // parameters to be optimal for long-running, memory allocation // intensive jobs. It is intended for machines with large diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 6cc1cfdc75769..0b48bde764d19 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -271,6 +271,8 @@ class Arguments : AllStatic { // Setup heap size static void set_heap_size(); + static void set_ergonomics_profiles_heap_size_max_ram_percentage(julong phys_mem); + // Bytecode rewriting static void set_bytecode_flags(); diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java new file mode 100644 index 0000000000000..120a64d5b8353 --- /dev/null +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package gc.ergonomics; + +/* + * @test TestErgonomicsProfiles + * @bug 8017462 + * @summary Ensure that ErgonomicsProfiles selects the desired profile + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.ergonomics.TestErgonomicsProfiles + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jtreg.SkippedException; +import jdk.test.whitebox.gc.GC; + +public class TestErgonomicsProfiles { + + public static void main(String[] args) throws Exception { + + testErgonomicProfile("shared", "shared"); + + testErgonomicProfile("dedicated", "dedicated"); + + //testInsideContainer("auto", "shared"); + } + + private static void verifyErgonomicProfile(OutputAnalyzer output, String expectedProfile) { + output.shouldHaveExitValue(0); // test should run succesfully + output.shouldContain(expectedProfile); + } + + private static void testErgonomicProfile(String ergonomicsProfile, String expectedProfile) throws Exception { + String[] baseArgs = {"-XX:ErgonomicsProfile=" + ergonomicsProfile}; + + // Base test with selected ergonomics profile + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); + verifyErgonomicProfile(output, expectedProfile); + } + + private static void testInsideContainer(String ergonomicsProfile, String expectedProfile) throws Exception { + if (!DockerTestUtils.canTestDocker()) { + return; + } + + final String imageNameAndTag = Common.imageName("basic"); + + DockerTestUtils.buildJdkContainerImage(imageNameAndTag); + + try { + DockerRunOptions opts = + new ∏(imageNameAndTag, "/jdk/bin/java", "-version"); + + DockerTestUtils.dockerRunJava(opts) + .shouldHaveExitValue(0) + .shouldContain(Platform.vmName); + + } finally { + if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { + DockerTestUtils.removeDockerImage(imageNameAndTag); + } + } + + // Base test with default ergonomics profile + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); + verifyErgonomicProfile(output, expectedProfile); + } + + +} From 439bae67c84cc23645d40e027cd155e0d64b1dd1 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 26 Apr 2024 08:25:43 -0700 Subject: [PATCH 23/31] jtreg test for ergo profile --- .../gc/ergonomics/TestErgonomicsProfiles.java | 82 ++++++++++++++----- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java index 120a64d5b8353..9de2baeed5ac4 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -36,60 +36,104 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; + +import jdk.test.lib.containers.docker.Common; +import jdk.test.lib.containers.docker.DockerRunOptions; +import jdk.test.lib.containers.docker.DockerTestUtils; + +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; + import jtreg.SkippedException; import jdk.test.whitebox.gc.GC; +/* + * @test TestErgonomicsProfiles + * @summary Ensure that ErgonomicsProfile fails with unsupported profile + * @requires docker.support + * @modules java.base/jdk.internal.misc + * java.management + * @library /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.ergonomics.TestErgonomicsProfiles + */ public class TestErgonomicsProfiles { public static void main(String[] args) throws Exception { - - testErgonomicProfile("shared", "shared"); - + testInvalidProfile(); + + // Test manual selection testErgonomicProfile("dedicated", "dedicated"); + testErgonomicProfile("shared", "shared"); + testDefaultErgonomicProfile("shared"); // default profile is shared. Change if default changes. + + // Test automatic selection and default, inside container + testInsideContainer("auto", "shared"); // default profile is shared even inside containers. Change if default changes. + + // TODO: test GC selection and Heap Size + } - //testInsideContainer("auto", "shared"); + private static void testInvalidProfile() throws Exception { + String[] baseArgs = {"-XX:ErgonomicsProfile=invalid", "-XX:+PrintFlagsFinal", "-version"}; + + // Base test with invalid ergonomics profile + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); + output + .shouldHaveExitValue(1) + .stderrContains("Unsupported ErgonomicsProfile: invalid"); } - private static void verifyErgonomicProfile(OutputAnalyzer output, String expectedProfile) { - output.shouldHaveExitValue(0); // test should run succesfully - output.shouldContain(expectedProfile); + private static void testDefaultErgonomicProfile(String expectedProfile) throws Exception { + String[] baseArgs = {"-XX:+PrintFlagsFinal", "-version"}; + + // Base test with default ergonomics profile + ProcessTools.executeLimitedTestJava(baseArgs) + .shouldHaveExitValue(0) + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); } private static void testErgonomicProfile(String ergonomicsProfile, String expectedProfile) throws Exception { - String[] baseArgs = {"-XX:ErgonomicsProfile=" + ergonomicsProfile}; + String[] baseArgs = {"-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal", "-version"}; // Base test with selected ergonomics profile - OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); - verifyErgonomicProfile(output, expectedProfile); + ProcessTools.executeLimitedTestJava(baseArgs) + .shouldHaveExitValue(0) + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); } private static void testInsideContainer(String ergonomicsProfile, String expectedProfile) throws Exception { + String[] javaOpts = {"-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal"}; + if (!DockerTestUtils.canTestDocker()) { + System.out.println("Docker not available, skipping test"); return; } - final String imageNameAndTag = Common.imageName("basic"); + final String imageNameAndTag = "ergoimage"; - DockerTestUtils.buildJdkContainerImage(imageNameAndTag); + String dockerfile = + "FROM --platform=linux/amd64 ubuntu:latest\n" + + "COPY /jdk /jdk\n" + + "ENV JAVA_HOME=/jdk\n" + + "CMD [\"/bin/bash\"]\n"; + + DockerTestUtils.buildJdkContainerImage(imageNameAndTag, dockerfile); try { DockerRunOptions opts = - new ∏(imageNameAndTag, "/jdk/bin/java", "-version"); + new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version", javaOpts); + opts.addDockerOpts("--platform=linux/amd64"); DockerTestUtils.dockerRunJava(opts) .shouldHaveExitValue(0) - .shouldContain(Platform.vmName); + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { DockerTestUtils.removeDockerImage(imageNameAndTag); } } - - // Base test with default ergonomics profile - OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); - verifyErgonomicProfile(output, expectedProfile); } - } From 9c4b3ec4563d3149b9dbef896f6b3e289599b228 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Sat, 27 Apr 2024 21:19:15 -0700 Subject: [PATCH 24/31] test max ram percentage --- .../gc/ergonomics/TestErgonomicsProfiles.java | 141 +++++++++++++----- 1 file changed, 100 insertions(+), 41 deletions(-) diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java index 9de2baeed5ac4..409506d24c076 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -41,6 +41,9 @@ import jdk.test.lib.containers.docker.DockerRunOptions; import jdk.test.lib.containers.docker.DockerTestUtils; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import jdk.test.lib.Platform; import jdk.test.lib.Utils; @@ -60,80 +63,136 @@ */ public class TestErgonomicsProfiles { - public static void main(String[] args) throws Exception { + private final static String imageNameAndTag = "ergoimage:latest"; + + private static final String DEDICATED_PROFILE = "dedicated"; + private static final String SHARED_PROFILE = "shared"; + private static final String AUTO_SELECTION = "auto"; + + public static void main(String[] args) throws Exception { testInvalidProfile(); // Test manual selection - testErgonomicProfile("dedicated", "dedicated"); - testErgonomicProfile("shared", "shared"); - testDefaultErgonomicProfile("shared"); // default profile is shared. Change if default changes. + testErgonomicProfile(DEDICATED_PROFILE, DEDICATED_PROFILE); + testErgonomicProfile(SHARED_PROFILE, SHARED_PROFILE); - // Test automatic selection and default, inside container - testInsideContainer("auto", "shared"); // default profile is shared even inside containers. Change if default changes. + testDefaultErgonomicProfile(SHARED_PROFILE); // default profile is shared. Change if default changes. - // TODO: test GC selection and Heap Size + // Tests inside containers + try { + // Prepare container image + prepareContainerImage(); + + // Test automatic selection and default, inside container + testProfileInsideContainer(AUTO_SELECTION, DEDICATED_PROFILE); + + // Test GC selection + // See GC selection in gcConfig.cpp::select_gc_ergonomically_dedicated + testGCSelection(DEDICATED_PROFILE, "UseSerialGC", 1, 1024); + //testGCSelection(DEDICATED_PROFILE, "UseZGC", 2, 16 * 1024); // 16G or more, use ZGC + //testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above 2GB, use G1 + testGCSelection(DEDICATED_PROFILE, "UseParallelGC", 2, 1024); // below 2G, use Parallel + + // Test Heap Size allocation (MaxRAMPercentage) + // See heap size MaxRAMPercentage ergo selection for dedicated in + // arguments.cpp::set_ergonomics_profiles_heap_size_max_ram_percentage + // Test MaxRAMPercentage selection for dedicated profile + testMaxRAMPercentageSelection(DEDICATED_PROFILE, 50.0, 256); // less than 0.5G, MaxRAMPercentage should be 50.0 + // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 75.0, 1 * 1024); // 0.5G to 4G, + // MaxRAMPercentage should be 75.0 + // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 80.0, 4 * 1024); // 4G to 6G, + // MaxRAMPercentage should be 80.0 + // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 85.0, 6 * 1024); // 6G to 16G, + // MaxRAMPercentage should be 85.0 + // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 90.0, 16 * 1024); // 16G or more, + // MaxRAMPercentage should be 90.0 + } finally { + if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { + DockerTestUtils.removeDockerImage(imageNameAndTag); + } + } } private static void testInvalidProfile() throws Exception { - String[] baseArgs = {"-XX:ErgonomicsProfile=invalid", "-XX:+PrintFlagsFinal", "-version"}; + String[] baseArgs = { "-XX:ErgonomicsProfile=invalid", "-XX:+PrintFlagsFinal", "-version" }; // Base test with invalid ergonomics profile OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); output - .shouldHaveExitValue(1) - .stderrContains("Unsupported ErgonomicsProfile: invalid"); + .shouldHaveExitValue(1) + .stderrContains("Unsupported ErgonomicsProfile: invalid"); } private static void testDefaultErgonomicProfile(String expectedProfile) throws Exception { - String[] baseArgs = {"-XX:+PrintFlagsFinal", "-version"}; + String[] baseArgs = { "-XX:+PrintFlagsFinal", "-version" }; // Base test with default ergonomics profile ProcessTools.executeLimitedTestJava(baseArgs) - .shouldHaveExitValue(0) - .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); + .shouldHaveExitValue(0) + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); } private static void testErgonomicProfile(String ergonomicsProfile, String expectedProfile) throws Exception { - String[] baseArgs = {"-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal", "-version"}; + String[] baseArgs = { "-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal", "-version" }; // Base test with selected ergonomics profile ProcessTools.executeLimitedTestJava(baseArgs) - .shouldHaveExitValue(0) - .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); + .shouldHaveExitValue(0) + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); } - private static void testInsideContainer(String ergonomicsProfile, String expectedProfile) throws Exception { - String[] javaOpts = {"-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal"}; - + private static void prepareContainerImage() throws Exception { if (!DockerTestUtils.canTestDocker()) { System.out.println("Docker not available, skipping test"); - return; + throw new SkippedException("Docker not available"); } - final String imageNameAndTag = "ergoimage"; - - String dockerfile = - "FROM --platform=linux/amd64 ubuntu:latest\n" + - "COPY /jdk /jdk\n" + - "ENV JAVA_HOME=/jdk\n" + - "CMD [\"/bin/bash\"]\n"; + String dockerfile = "FROM --platform=linux/amd64 ubuntu:latest\n" + + "COPY /jdk /jdk\n" + + "ENV JAVA_HOME=/jdk\n" + + "CMD [\"/bin/bash\"]\n"; DockerTestUtils.buildJdkContainerImage(imageNameAndTag, dockerfile); + } - try { - DockerRunOptions opts = - new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version", javaOpts); - opts.addDockerOpts("--platform=linux/amd64"); - - DockerTestUtils.dockerRunJava(opts) - .shouldHaveExitValue(0) - .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); - - } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageNameAndTag); - } - } + private static void testProfileInsideContainer(String ergonomicsProfile, String expectedProfile) throws Exception { + String[] javaOpts = { "-XX:ErgonomicsProfile=" + ergonomicsProfile, "-XX:+PrintFlagsFinal" }; + + DockerRunOptions opts = new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version", javaOpts); + opts.addDockerOpts("--rm"); + + DockerTestUtils.dockerRunJava(opts) + .shouldHaveExitValue(0) + .stdoutShouldMatch("ErgonomicsProfile.*" + expectedProfile); + } + + public static void testGCSelection(String profile, String expectedGC, int cpuCount, int memoryInMB) throws Exception { + String[] javaOpts = { "-XX:ErgonomicsProfile=" + profile, "-XX:+PrintFlagsFinal" }; + + DockerRunOptions opts = new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version", javaOpts); + opts.addDockerOpts("--rm", "--cpus", String.valueOf(cpuCount), "--memory", memoryInMB + "m"); + + OutputAnalyzer output = DockerTestUtils.dockerRunJava(opts); + output.shouldHaveExitValue(0); + + // Check GC + output.stdoutShouldMatch(expectedGC + ".*true"); + } + + private static void testMaxRAMPercentageSelection(String profile, double expectedMaxRAMPercentage, int physMem) + throws Exception { + String[] javaOpts = { "-XX:ErgonomicsProfile=" + profile, "-XX:+PrintFlagsFinal" }; + + DockerRunOptions opts = new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version", javaOpts); + opts.addDockerOpts("--rm", "--memory", physMem + "m"); + + // Run JVM with the given arguments + OutputAnalyzer output = DockerTestUtils.dockerRunJava(opts); + output.shouldHaveExitValue(0); + + // Check that MaxRAMPercentage is set to the expected value + output.shouldHaveExitValue(0); + output.stdoutShouldMatch("MaxRAMPercentage.*" + expectedMaxRAMPercentage); } } From a7db925cddc3c117f15a5a6d6f1e466bc0ed404c Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Sun, 28 Apr 2024 22:18:45 -0700 Subject: [PATCH 25/31] Tests for ergo profiles --- .../gc/ergonomics/TestErgonomicsProfiles.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java index 409506d24c076..f61e32e25fca8 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -89,24 +89,27 @@ public static void main(String[] args) throws Exception { // Test GC selection // See GC selection in gcConfig.cpp::select_gc_ergonomically_dedicated testGCSelection(DEDICATED_PROFILE, "UseSerialGC", 1, 1024); - //testGCSelection(DEDICATED_PROFILE, "UseZGC", 2, 16 * 1024); // 16G or more, use ZGC - //testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above 2GB, use G1 testGCSelection(DEDICATED_PROFILE, "UseParallelGC", 2, 1024); // below 2G, use Parallel + testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above 2GB, use G1 + testGCSelection(DEDICATED_PROFILE, "UseZGC", 2, 16 * 1024); // 16G or more, use ZGC // Test Heap Size allocation (MaxRAMPercentage) // See heap size MaxRAMPercentage ergo selection for dedicated in // arguments.cpp::set_ergonomics_profiles_heap_size_max_ram_percentage // Test MaxRAMPercentage selection for dedicated profile - testMaxRAMPercentageSelection(DEDICATED_PROFILE, 50.0, 256); // less than 0.5G, MaxRAMPercentage should be 50.0 - // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 75.0, 1 * 1024); // 0.5G to 4G, - // MaxRAMPercentage should be 75.0 - // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 80.0, 4 * 1024); // 4G to 6G, - // MaxRAMPercentage should be 80.0 - // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 85.0, 6 * 1024); // 6G to 16G, - // MaxRAMPercentage should be 85.0 - // testMaxRAMPercentageSelection(DEDICATED_PROFILE, 90.0, 16 * 1024); // 16G or more, - // MaxRAMPercentage should be 90.0 - } finally { + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "50.0", 511); // less than 0.5G, MaxRAMPercentage should be 50.0 + // MaxRAMPercentage should be 75.0 between => 0.5G to <4G + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "75.0", 512); + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "75.0", 4 * 1024 - 1); + // MaxRAMPercentage should be 80.0 between => 4G to <6G + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "80.0", 4 * 1024); + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "80.0", 6 * 1024 - 1); + // MaxRAMPercentage should be 85.0 between => 6G to <16G + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "85.0", 6 * 1024); + testMaxRAMPercentageSelection(DEDICATED_PROFILE, "85.0", 16 * 1024 - 1); + // MaxRAMPercentage should be 90.0 between => 16G or more + // testMaxRAMPercentageSelection(DEDICATED_PROFILE, "90.0", 16 * 1024); + } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { DockerTestUtils.removeDockerImage(imageNameAndTag); } @@ -179,7 +182,7 @@ public static void testGCSelection(String profile, String expectedGC, int cpuCou output.stdoutShouldMatch(expectedGC + ".*true"); } - private static void testMaxRAMPercentageSelection(String profile, double expectedMaxRAMPercentage, int physMem) + private static void testMaxRAMPercentageSelection(String profile, String expectedMaxRAMPercentage, int physMem) throws Exception { String[] javaOpts = { "-XX:ErgonomicsProfile=" + profile, "-XX:+PrintFlagsFinal" }; From 4cd37d08d1d64358a6b98e3953a4f15a08440a14 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Wed, 8 May 2024 18:02:59 +0000 Subject: [PATCH 26/31] Do not consider ZGC for now --- src/hotspot/share/gc/shared/gcConfig.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index b42c6d1c1a4b3..64fed5eed1b51 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -124,10 +124,6 @@ void select_gc_ergonomically_dedicated() { if (os::active_processor_count() <= 1) { #if INCLUDE_SERIALGC FLAG_SET_ERGO_IF_DEFAULT(UseSerialGC, true); -#endif - } else if (phys_mem >= 16*G) { -#if INCLUDE_ZGC - FLAG_SET_ERGO_IF_DEFAULT(UseZGC, true); #endif } else if (phys_mem > 2048*M) { #if INCLUDE_G1GC From 6232c643c1dc6d905bb685dc6c7a9fee0cbbe199 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Thu, 9 May 2024 14:23:33 -0700 Subject: [PATCH 27/31] Remove getGCName API from Runtime MBean and VMManagement --- src/hotspot/share/gc/shared/gcConfig.cpp | 9 --------- src/hotspot/share/gc/shared/gcConfig.hpp | 2 -- .../classes/java/lang/management/RuntimeMXBean.java | 8 -------- .../share/classes/sun/management/RuntimeImpl.java | 4 ---- .../share/classes/sun/management/VMManagement.java | 1 - .../share/classes/sun/management/VMManagementImpl.java | 4 ---- 6 files changed, 28 deletions(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 64fed5eed1b51..7dfd58dbf2da2 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -85,7 +85,6 @@ SHENANDOAHGC_ONLY_ARG(IncludedGC(UseShenandoahGC, CollectedHeap::Shenandoah, GCArguments* GCConfig::_arguments = nullptr; bool GCConfig::_gc_selected_ergonomically = false; -const char* GCConfig::_gc_name = nullptr; void GCConfig::fail_if_non_included_gc_is_selected() { NOT_EPSILONGC( FAIL_IF_SELECTED(UseEpsilonGC)); @@ -201,10 +200,6 @@ GCArguments* GCConfig::select_gc() { // Exactly one GC selected FOR_EACH_INCLUDED_GC(gc) { if (gc->_flag) { - _gc_name = gc->_hs_err_name; - if (ZGenerational) { - _gc_name = "z gen gc"; - } return &gc->_arguments; } } @@ -247,10 +242,6 @@ bool GCConfig::is_gc_selected_ergonomically() { return _gc_selected_ergonomically; } -const char* GCConfig::gc_name() { - return _gc_name; -} - const char* GCConfig::hs_err_name() { if (is_exactly_one_gc_selected()) { // Exactly one GC selected diff --git a/src/hotspot/share/gc/shared/gcConfig.hpp b/src/hotspot/share/gc/shared/gcConfig.hpp index c7d204dfef0ca..9b0da3ad528a8 100644 --- a/src/hotspot/share/gc/shared/gcConfig.hpp +++ b/src/hotspot/share/gc/shared/gcConfig.hpp @@ -34,7 +34,6 @@ class GCConfig : public AllStatic { private: static GCArguments* _arguments; static bool _gc_selected_ergonomically; - static const char* _gc_name; static void fail_if_non_included_gc_is_selected(); static bool is_no_gc_selected(); @@ -54,7 +53,6 @@ class GCConfig : public AllStatic { static const char* hs_err_name(CollectedHeap::Name name); static GCArguments* arguments(); - static const char* gc_name(); }; #endif // SHARE_GC_SHARED_GCCONFIG_HPP diff --git a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java index e614fcbc035c3..63f7f878d26c8 100644 --- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java +++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java @@ -371,12 +371,4 @@ public default long getPid() { * @return the name of the selected ergonomics profile */ public String getJvmErgonomicsProfile(); - - /** - * Returns the name of the active garbage collector. - * - * @return the name of the active GC in this runtime - */ - public String getGCName(); - } diff --git a/src/java.management/share/classes/sun/management/RuntimeImpl.java b/src/java.management/share/classes/sun/management/RuntimeImpl.java index 9eb14c339c952..f13d075402af3 100644 --- a/src/java.management/share/classes/sun/management/RuntimeImpl.java +++ b/src/java.management/share/classes/sun/management/RuntimeImpl.java @@ -137,10 +137,6 @@ public String getJvmErgonomicsProfile() { return jvm.getErgonomicsProfile(); } - public String getGCName() { - return jvm.getGCName(); - } - public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); } diff --git a/src/java.management/share/classes/sun/management/VMManagement.java b/src/java.management/share/classes/sun/management/VMManagement.java index e43895738187b..b559c2f9cd97e 100644 --- a/src/java.management/share/classes/sun/management/VMManagement.java +++ b/src/java.management/share/classes/sun/management/VMManagement.java @@ -74,7 +74,6 @@ public interface VMManagement { public long getUptime(); public int getAvailableProcessors(); public String getErgonomicsProfile(); - public String getGCName(); // Compilation Subsystem public String getCompilerName(); diff --git a/src/java.management/share/classes/sun/management/VMManagementImpl.java b/src/java.management/share/classes/sun/management/VMManagementImpl.java index e0e591146191b..7a5c64241f412 100644 --- a/src/java.management/share/classes/sun/management/VMManagementImpl.java +++ b/src/java.management/share/classes/sun/management/VMManagementImpl.java @@ -205,10 +205,6 @@ public String getErgonomicsProfile() { return System.getProperty("java.vm.ergonomics.profile"); } - public String getGCName() { - return System.getProperty("java.vm.gc.name"); - } - // Compilation Subsystem public String getCompilerName() { @SuppressWarnings("removal") From fc3e25b2306728023281d69afa1eca1f6d37091f Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 10 May 2024 08:36:47 -0700 Subject: [PATCH 28/31] Update src/hotspot/share/gc/shared/gcConfig.cpp Co-authored-by: David Schlosnagle --- src/hotspot/share/gc/shared/gcConfig.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index 7dfd58dbf2da2..c9d4bc8ae4517 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -115,7 +115,6 @@ void select_gc_ergonomically_shared() { // It first checks the physical memory available on the system and the number of active processors. // Depending on these factors, it sets the appropriate GC flag to true using the FLAG_SET_ERGO_IF_DEFAULT macro. // If the system has only one active processor, it selects the Serial GC, no matter how much memory is available. -// If the system has more than one active processor and the physical memory is greater than or equal to 16GB, it selects the ZGC. // If the physical memory is greater than 2GB, it selects the G1GC. // Otherwise, it selects the Parallel GC. void select_gc_ergonomically_dedicated() { From 7aa4ec5a51c3bbea893c8cad5ecfae9069eca790 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 10 May 2024 16:51:27 +0000 Subject: [PATCH 29/31] ZGC is not part of initial implementation --- test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java index f61e32e25fca8..28496cc5865d7 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -91,7 +91,6 @@ public static void main(String[] args) throws Exception { testGCSelection(DEDICATED_PROFILE, "UseSerialGC", 1, 1024); testGCSelection(DEDICATED_PROFILE, "UseParallelGC", 2, 1024); // below 2G, use Parallel testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above 2GB, use G1 - testGCSelection(DEDICATED_PROFILE, "UseZGC", 2, 16 * 1024); // 16G or more, use ZGC // Test Heap Size allocation (MaxRAMPercentage) // See heap size MaxRAMPercentage ergo selection for dedicated in From 63bc9382084397712c0a8ba36102178829e9b901 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 10 May 2024 16:51:27 +0000 Subject: [PATCH 30/31] ZGC is not part of initial implementation --- .../jtreg/gc/ergonomics/TestErgonomicsProfiles.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java index f61e32e25fca8..8e08ee3193302 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestErgonomicsProfiles.java @@ -88,10 +88,9 @@ public static void main(String[] args) throws Exception { // Test GC selection // See GC selection in gcConfig.cpp::select_gc_ergonomically_dedicated - testGCSelection(DEDICATED_PROFILE, "UseSerialGC", 1, 1024); - testGCSelection(DEDICATED_PROFILE, "UseParallelGC", 2, 1024); // below 2G, use Parallel - testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above 2GB, use G1 - testGCSelection(DEDICATED_PROFILE, "UseZGC", 2, 16 * 1024); // 16G or more, use ZGC + testGCSelection(DEDICATED_PROFILE, "UseSerialGC", 1, 1024); // no matter how much memory, use serial if 1 proc + testGCSelection(DEDICATED_PROFILE, "UseParallelGC", 2, 1024); // <=2G, use Parallel + testGCSelection(DEDICATED_PROFILE, "UseG1GC", 2, 2 * 1024 + 1); // above >2GB, use G1 // Test Heap Size allocation (MaxRAMPercentage) // See heap size MaxRAMPercentage ergo selection for dedicated in From da546d2cf4be917136f8e500c7adbb61366efa19 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Fri, 10 May 2024 17:11:11 +0000 Subject: [PATCH 31/31] Add AutoErgonomicsProfile bool flag to enable auto selection --- src/hotspot/share/gc/shared/gc_globals.hpp | 3 ++- src/hotspot/share/runtime/arguments.cpp | 18 +++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 12a7348e13c7b..5632baf7f384f 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -125,9 +125,10 @@ "Use the Shenandoah garbage collector") \ \ /* notice: once stable enough, goal is to change default to auto */ \ + product(bool, AutoErgonomicsProfile, false, "Use automatic selection of " \ + "ergonomics profiles.") \ product(ccstr, ErgonomicsProfile, "shared", \ "Ergonomics profile to use. " \ - "\"auto\" for automatic selection. " \ "\"shared\" for traditional environments (default). " \ "\"dedicated\" for environments with dedicated resources.") \ \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 59fc5bd36c3f0..5250fd036b48c 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1442,10 +1442,13 @@ void Arguments::set_use_compressed_klass_ptrs() { } static void validate_ergonomics_profile() { - if ( + if (AutoErgonomicsProfile && FLAG_IS_CMDLINE(ErgonomicsProfile)) { + vm_exit_during_initialization(err_msg("Automatic ergonomics profile selection is enabled. Do not set a specific profile at the same time.")); + } + + if (FLAG_IS_CMDLINE(ErgonomicsProfile) && strcmp(ErgonomicsProfile, "shared") != 0 && - strcmp(ErgonomicsProfile, "dedicated") != 0 && - strcmp(ErgonomicsProfile, "auto") != 0){ + strcmp(ErgonomicsProfile, "dedicated") != 0) { vm_exit_during_initialization(err_msg("Unsupported ErgonomicsProfile: %s", ErgonomicsProfile)); } } @@ -1463,8 +1466,6 @@ void Arguments::set_conservative_max_heap_alignment() { jint Arguments::set_ergonomics_flags() { GCConfig::initialize(); - // Store the name of the selected GC - PropertyList_add(&_system_properties, new SystemProperty("java.vm.gc.name", GCConfig::gc_name(), false)); set_conservative_max_heap_alignment(); @@ -1483,7 +1484,7 @@ void Arguments::set_ergonomics_profile() { validate_ergonomics_profile(); // Check if the value is 'auto'. - if (strcmp(ErgonomicsProfile, "auto") == 0) { + if (AutoErgonomicsProfile) { // Set the ergonomics profile based on platform. // If it is a Linux environment, check if we are inside a container. // If yes, we apply dedicated automatically. @@ -1491,9 +1492,12 @@ void Arguments::set_ergonomics_profile() { #ifdef LINUX if (OSContainer::is_containerized()){ FLAG_SET_ERGO(ErgonomicsProfile, "dedicated"); - } else + } #endif //LINUX + + if (FLAG_IS_DEFAULT(ErgonomicsProfile)) { FLAG_SET_ERGO(ErgonomicsProfile, "shared"); + } } // Store so we can expose through JMX RuntimeMBean