From 4e80471616c25bf80590f24a81f84a0a7ea3a8cc Mon Sep 17 00:00:00 2001 From: Peter Veentjer Date: Mon, 18 Nov 2019 10:59:14 +0200 Subject: [PATCH] Fixes issue AIX and OSMBean getFreePhysicalMemorySize A flag is added to supress retrieving this value. On AIX there is one customer that runs into multi seconds execution times for this method. --- .../TimedMemberStateFactoryHelper.java | 6 ++ .../metricsets/OperatingSystemMetricSet.java | 15 ++++- .../util/OperatingSystemMXBeanSupport.java | 22 +++++++ ...rt_FreePhysicalMemorySizeDisabledTest.java | 65 +++++++++++++++++++ 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 hazelcast/src/test/java/com/hazelcast/util/OperatingSystemMXBeanSupport_FreePhysicalMemorySizeDisabledTest.java diff --git a/hazelcast/src/main/java/com/hazelcast/internal/management/TimedMemberStateFactoryHelper.java b/hazelcast/src/main/java/com/hazelcast/internal/management/TimedMemberStateFactoryHelper.java index 246d1c153108d..1e1767f411b1f 100644 --- a/hazelcast/src/main/java/com/hazelcast/internal/management/TimedMemberStateFactoryHelper.java +++ b/hazelcast/src/main/java/com/hazelcast/internal/management/TimedMemberStateFactoryHelper.java @@ -32,6 +32,7 @@ import com.hazelcast.spi.ExecutionService; import com.hazelcast.spi.ProxyService; import com.hazelcast.spi.impl.operationservice.InternalOperationService; +import com.hazelcast.util.OperatingSystemMXBeanSupport; import com.hazelcast.util.executor.ManagedExecutorService; import java.lang.management.ClassLoadingMXBean; @@ -149,6 +150,11 @@ static void createRuntimeProps(MemberStateImpl memberState) { } private static Long get(OperatingSystemMXBean mbean, String methodName, Long defaultValue) { + if (OperatingSystemMXBeanSupport.GET_FREE_PHYSICAL_MEMORY_SIZE_DISABLED + && methodName.equals("getFreePhysicalMemorySize")) { + return defaultValue; + } + try { Method method = mbean.getClass().getMethod(methodName); method.setAccessible(true); diff --git a/hazelcast/src/main/java/com/hazelcast/internal/metrics/metricsets/OperatingSystemMetricSet.java b/hazelcast/src/main/java/com/hazelcast/internal/metrics/metricsets/OperatingSystemMetricSet.java index 0e0c0e9af1825..0ad0d66b61221 100644 --- a/hazelcast/src/main/java/com/hazelcast/internal/metrics/metricsets/OperatingSystemMetricSet.java +++ b/hazelcast/src/main/java/com/hazelcast/internal/metrics/metricsets/OperatingSystemMetricSet.java @@ -21,6 +21,7 @@ import com.hazelcast.internal.metrics.MetricsRegistry; import com.hazelcast.logging.ILogger; import com.hazelcast.logging.Logger; +import com.hazelcast.util.OperatingSystemMXBeanSupport; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; @@ -78,7 +79,17 @@ public double get(OperatingSystemMXBean bean) { } static void registerMethod(MetricsRegistry metricsRegistry, Object osBean, String methodName, String name) { - registerMethod(metricsRegistry, osBean, methodName, name, 1); + if (OperatingSystemMXBeanSupport.GET_FREE_PHYSICAL_MEMORY_SIZE_DISABLED + && methodName.equals("getFreePhysicalMemorySize")) { + metricsRegistry.register(osBean, name, MANDATORY, new LongProbeFunction() { + @Override + public long get(Object source) { + return -1; + } + }); + } else { + registerMethod(metricsRegistry, osBean, methodName, name, 1); + } } private static void registerMethod(MetricsRegistry metricsRegistry, Object osBean, String methodName, String name, @@ -111,7 +122,7 @@ public double get(Object bean) throws Exception { * * @param source the source object. * @param methodName the name of the method to retrieve. - * @param name the probe name + * @param name the probe name * @return the method */ private static Method getMethod(Object source, String methodName, String name) { diff --git a/hazelcast/src/main/java/com/hazelcast/util/OperatingSystemMXBeanSupport.java b/hazelcast/src/main/java/com/hazelcast/util/OperatingSystemMXBeanSupport.java index 9ef7de2fedf3c..f92229c85c648 100644 --- a/hazelcast/src/main/java/com/hazelcast/util/OperatingSystemMXBeanSupport.java +++ b/hazelcast/src/main/java/com/hazelcast/util/OperatingSystemMXBeanSupport.java @@ -26,14 +26,31 @@ /** * Support class for reading attributes from OperatingSystemMXBean. */ +@SuppressWarnings("checkstyle:declarationorder") public final class OperatingSystemMXBeanSupport { + static final String COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED = "hazelcast.os.free.physical.memory.disabled"; + /** + * On AIX it can happen that the getFreePhysicalMemorySize method is very slow. + * This flags allows one to prevent executing this method and returns the default. + * + * This field is made volatile for testing purposes. Having this field volatile isn't relevant for performance + * since the logic for obtaining the attribute isn't very efficient. + */ + @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:staticvariablename"}) + public static volatile boolean GET_FREE_PHYSICAL_MEMORY_SIZE_DISABLED + = Boolean.getBoolean(COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED); private static final OperatingSystemMXBean OPERATING_SYSTEM_MX_BEAN = ManagementFactory.getOperatingSystemMXBean(); private static final double PERCENTAGE_MULTIPLIER = 100d; private OperatingSystemMXBeanSupport() { } + // for testing purposes. + static void reload() { + GET_FREE_PHYSICAL_MEMORY_SIZE_DISABLED = Boolean.getBoolean(COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED); + } + /** * Reads a long attribute from OperatingSystemMXBean. * @@ -41,9 +58,14 @@ private OperatingSystemMXBeanSupport() { * @param defaultValue default value if the attribute value is null * @return value of the attribute */ + @SuppressWarnings("checkstyle:npathcomplexity") public static long readLongAttribute(String attributeName, long defaultValue) { try { String methodName = "get" + attributeName; + if (GET_FREE_PHYSICAL_MEMORY_SIZE_DISABLED && methodName.equals("getFreePhysicalMemorySize")) { + return defaultValue; + } + OperatingSystemMXBean systemMXBean = OPERATING_SYSTEM_MX_BEAN; Method method = systemMXBean.getClass().getMethod(methodName); // the method is public in Java 9 diff --git a/hazelcast/src/test/java/com/hazelcast/util/OperatingSystemMXBeanSupport_FreePhysicalMemorySizeDisabledTest.java b/hazelcast/src/test/java/com/hazelcast/util/OperatingSystemMXBeanSupport_FreePhysicalMemorySizeDisabledTest.java new file mode 100644 index 0000000000000..e64d12b128e99 --- /dev/null +++ b/hazelcast/src/test/java/com/hazelcast/util/OperatingSystemMXBeanSupport_FreePhysicalMemorySizeDisabledTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008-2019, Hazelcast, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hazelcast.util; + +import com.hazelcast.test.HazelcastSerialClassRunner; +import com.hazelcast.test.annotation.QuickTest; +import org.junit.After; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import static com.hazelcast.util.OperatingSystemMXBeanSupport.COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +@RunWith(HazelcastSerialClassRunner.class) +@Category(QuickTest.class) +@SuppressWarnings("checkstyle:magicnumber") +public class OperatingSystemMXBeanSupport_FreePhysicalMemorySizeDisabledTest { + + private static final int DEFAULT_VALUE = -1; + + @After + public void after() { + System.clearProperty(COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED); + OperatingSystemMXBeanSupport.reload(); + } + + @Test + public void whenDisabled() { + System.setProperty(COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED, "true"); + OperatingSystemMXBeanSupport.reload(); + long result = OperatingSystemMXBeanSupport.readLongAttribute("FreePhysicalMemorySize", DEFAULT_VALUE); + assertEquals(DEFAULT_VALUE, result); + } + + @Test + public void whenDefault() { + OperatingSystemMXBeanSupport.reload(); + long result = OperatingSystemMXBeanSupport.readLongAttribute("FreePhysicalMemorySize", DEFAULT_VALUE); + assertNotEquals(DEFAULT_VALUE, result); + } + + @Test + public void whenEnabled() { + System.setProperty(COM_HAZELCAST_FREE_PHYSICAL_MEMORY_SIZE_DISABLED, "false"); + OperatingSystemMXBeanSupport.reload(); + long result = OperatingSystemMXBeanSupport.readLongAttribute("FreePhysicalMemorySize", DEFAULT_VALUE); + assertNotEquals(DEFAULT_VALUE, result); + } +}