Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
package org.apache.hadoop.hbase.util;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Locale;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
Expand All @@ -37,6 +35,7 @@
import org.apache.hbase.thirdparty.io.netty.buffer.ByteBufAllocatorMetric;
import org.apache.hbase.thirdparty.io.netty.buffer.ByteBufAllocatorMetricProvider;
import org.apache.hbase.thirdparty.io.netty.buffer.PooledByteBufAllocator;
import org.apache.hbase.thirdparty.io.netty.util.internal.PlatformDependent;

/**
* Utilities for interacting with and monitoring DirectByteBuffer allocations.
Expand Down Expand Up @@ -77,36 +76,16 @@ public class DirectMemoryUtils {
HAS_MEMORY_USED_ATTRIBUTE = a != null;
}

/**
* @return the setting of -XX:MaxDirectMemorySize as a long. Returns 0 if -XX:MaxDirectMemorySize
* is not set.
*/
/** Returns the direct memory limit of the current progress */
public static long getDirectMemorySize() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this method be called by multiple threads? Let's initialize it while loading the class?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently not likely, so I make this lazily.

But I think you are right, it's better to evaluate it first. Pushed a new commit to address this. Thanks Duo. @Apache9

RuntimeMXBean runtimemxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimemxBean.getInputArguments();
long multiplier = 1; // for the byte case.
for (String s : arguments) {
if (s.contains("-XX:MaxDirectMemorySize=")) {
String memSize = s.toLowerCase(Locale.ROOT).replace("-xx:maxdirectmemorysize=", "").trim();

if (memSize.contains("k")) {
multiplier = 1024;
}

else if (memSize.contains("m")) {
multiplier = 1048576;
}

else if (memSize.contains("g")) {
multiplier = 1073741824;
}
memSize = memSize.replaceAll("[^\\d]", "");

long retValue = Long.parseLong(memSize);
return retValue * multiplier;
}
try {
Field directMemoryLimit = PlatformDependent.class.getDeclaredField("MAX_DIRECT_MEMORY");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing Duo @Apache9

I think maybe we cannot. Here is the reason:

  1. in the master branch, the hbase-thirdparty version is 4.1.2
    https://github.com/apache/hbase/blob/master/pom.xml#L870

  2. the the hbase-thirdparty 4.1.2, the netty version is 4.1.82.Final
    https://github.com/apache/hbase-thirdparty/blob/230e5ebc432c2004b4ab744dca6627697f9f2a76/pom.xml#L135

  3. in the netty 4.1.82.Final, the return value is DIRECT_MEMORY_LIMIT
    https://github.com/netty/netty/blob/47799635143d7a11b56c4a4e9a1e65ca221d28ca/common/src/main/java/io/netty/util/internal/PlatformDependent.java#L407

however, the value can be overrided if org.apache.hbase.thirdparty.io.netty.maxDirectMemory is set.
https://github.com/netty/netty/blob/47799635143d7a11b56c4a4e9a1e65ca221d28ca/common/src/main/java/io/netty/util/internal/PlatformDependent.java#L179

So I think this API is not stable enough. That's the reason why I give up this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, on branch 4.1 it returns the netty limit. Should we provide a fallback way if netty one is avaiable?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In both version , the meaning of MAX_DIRECT_MEMORY is the same, It represents the direct memory size that the JVM process can obtain. So I think the value of MAX_DIRECT_MEMORY is fine. Maybe there's no need to fallback ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use reflection to get this field so it will not trigger a compilation error if netty changes this field in the future, so we can not find it when upgrading netty.

The estimateMaxDirectMemory method is public, so maybe we could just call it and store the return value by our own?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, in the old version, this method is private. Didn't notice it has been public now. Thanks for point it out.

You are right,this is better than reflection. I'll fix this. Thanks Duo.@Apache9

directMemoryLimit.setAccessible(true);
return directMemoryLimit.getLong(PlatformDependent.class);
} catch (Exception e) {
LOG.warn("Failed get direct memory size", e);
return 0L;
}
return 0;
}

/** Returns the current amount of direct memory used. */
Expand Down