You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2015/09/08 14:29:03 UTC

svn commit: r1701786 - /qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java

Author: orudyy
Date: Tue Sep  8 12:29:02 2015
New Revision: 1701786

URL: http://svn.apache.org/r1701786
Log:
QPID-6726: [Java Broker] Use reflection for getting maxDirectmemorySize with HotSpotDiagnosticMXBean and fall back to evaluation of maxDirectmemorySize from command line arguments when HotSpotDiagnosticMXBean is not not available in JVM

work by Lorenz Quack <qu...@gmail.com> and Alex Rudyy <or...@apache.org>

Modified:
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1701786&r1=1701785&r2=1701786&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Tue Sep  8 12:29:02 2015
@@ -21,27 +21,32 @@
 package org.apache.qpid.server.model.adapter;
 
 import java.lang.management.ManagementFactory;
+import java.lang.management.PlatformManagedObject;
+import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.security.AccessControlException;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.UUID;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.security.auth.Subject;
 
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
 import org.apache.qpid.bytebuffer.QpidByteBuffer;
 import org.apache.qpid.server.logging.QpidLoggerTurboFilter;
 import org.apache.qpid.server.logging.StartupAppender;
+import org.apache.qpid.server.util.ServerScopedRuntimeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -885,20 +890,85 @@ public class BrokerAdapter extends Abstr
 
     public static long getMaxDirectMemorySize()
     {
-        final HotSpotDiagnosticMXBean diagnostiMXBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
         long maxMemory = 0;
-        if (diagnostiMXBean != null)
+        try
         {
-            VMOption vmOption = diagnostiMXBean.getVMOption("MaxDirectMemorySize");
-            if (vmOption != null)
-            {
-                maxMemory = Long.parseLong(vmOption.getValue());
-            };
+            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+            Class<?> hotSpotDiagnosticMXBeanClass = Class.forName("com.sun.management.HotSpotDiagnosticMXBean", true, systemClassLoader);
+            Class<?> vmOptionClass = Class.forName("com.sun.management.VMOption", true, systemClassLoader);
+
+            Object hotSpotDiagnosticMXBean = ManagementFactory.getPlatformMXBean((Class<? extends PlatformManagedObject>)hotSpotDiagnosticMXBeanClass);
+            Method getVMOption = hotSpotDiagnosticMXBeanClass.getDeclaredMethod("getVMOption", String.class);
+            Object vmOption = getVMOption.invoke(hotSpotDiagnosticMXBean, "MaxDirectMemorySize");
+            Method getValue = vmOptionClass.getDeclaredMethod("getValue");
+            String maxDirectMemoryAsString = (String)getValue.invoke(vmOption);
+            maxMemory = Long.parseLong(maxDirectMemoryAsString);
         }
+        catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e)
+        {
+            LOGGER.debug("Cannot determine direct memory max size using com.sun.management.HotSpotDiagnosticMXBean: " + e.getMessage());
+        }
+        catch (InvocationTargetException e)
+        {
+            throw new ServerScopedRuntimeException("Unexpected exception in evaluation of MaxDirectMemorySize with HotSpotDiagnosticMXBean", e.getTargetException());
+        }
+
         if (maxMemory == 0)
         {
-            maxMemory = Runtime.getRuntime().maxMemory();
+            Pattern maxDirectMemorySizeArgumentPattern = Pattern.compile("^\\s*-XX:MaxDirectMemorySize\\s*=\\s*(\\d+)\\s*([KkMmGgTt]?)\\s*$");
+            RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean();
+            List<String> inputArguments = RuntimemxBean.getInputArguments();
+            boolean argumentFound = false;
+            for (String argument : inputArguments)
+            {
+                Matcher matcher = maxDirectMemorySizeArgumentPattern.matcher(argument);
+                if (matcher.matches())
+                {
+                    argumentFound = true;
+                    maxMemory = Long.parseLong(matcher.group(1));
+                    String unit = matcher.group(2);
+                    char unitChar = "".equals(unit) ? 0 : unit.charAt(0);
+                    switch (unitChar)
+                    {
+                        case 'k':
+                        case 'K':
+                            maxMemory *= 1024l;
+                            break;
+                        case 'm':
+                        case 'M':
+                            maxMemory *= 1024l * 1024l;
+                            break;
+                        case 'g':
+                        case 'G':
+                            maxMemory *= 1024l * 1024l * 1024l;
+                            break;
+                        case 't':
+                        case 'T':
+                            maxMemory *= 1024l * 1024l * 1024l * 1024l;
+                            break;
+                        case 0:
+                            // noop
+                            break;
+                        default:
+                            throw new IllegalStateException("Unexpected unit character in MaxDirectMemorySize argument : " + argument);
+                    }
+                    // do not break; continue. Oracle and IBM JVMs use the last value when argument is specified multiple times
+                }
+            }
+
+            if (maxMemory == 0)
+            {
+                if (argumentFound)
+                {
+                    throw new IllegalArgumentException("Qpid Broker cannot operate with 0 direct memory. Please, set JVM argument MaxDirectMemorySize to non-zero value");
+                }
+                else
+                {
+                    maxMemory = Runtime.getRuntime().maxMemory();
+                }
+            }
         }
+
         return maxMemory;
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org