Skip to content

Commit

Permalink
Fixes issue AIX and OSMBean getFreePhysicalMemorySize
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pveentjer committed Nov 20, 2019
1 parent d3fa414 commit 4e80471
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Object>() {
@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,
Expand Down Expand Up @@ -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) {
Expand Down
Expand Up @@ -26,24 +26,46 @@
/**
* 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.
*
* @param attributeName name of the attribute
* @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
Expand Down
@@ -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);
}
}

0 comments on commit 4e80471

Please sign in to comment.