clintropolis commented on a change in pull request #7606: Set direct memory if 
unable to detect JVM config
URL: https://github.com/apache/incubator-druid/pull/7606#discussion_r282326369
 
 

 ##########
 File path: 
processing/src/main/java/org/apache/druid/query/DruidProcessingConfig.java
 ##########
 @@ -52,7 +52,22 @@ public int intermediateComputeSizeBytes()
       return computedBufferSizeBytes.get();
     }
 
-    long directSizeBytes = 
JvmUtils.getRuntimeInfo().getDirectMemorySizeBytes();
+    long directSizeBytes;
+    try {
+      directSizeBytes = JvmUtils.getRuntimeInfo().getDirectMemorySizeBytes();
 
 Review comment:
   I haven't been following the jdk9+ compat PRs too closely so apologies if 
this has been discussed elsewhere, but if we aren't afraid of getting a bit 
dirty there appear to be at least 2 ways we could source this information which 
I tested up to jdk11 (didn't have 12 handy).
   
   [This stuff is still in the jdk, at least as of 12, but it's now in 
`jdk.internal.misc.VM`](https://github.com/AdoptOpenJDK/openjdk-jdk12u/blob/master/src/java.base/share/classes/jdk/internal/misc/VM.java#L130).
 I imagine the java people would tell us that neither of the ways I could get 
this information are legit to use.. but they probably would've said that about 
using `sun.misc.VM` in the first place. 
   
   The first and less intrusive is to reflect it out of `java.nio.Bits`, which 
stores the value it gets from `jdk.internal.misc.VM` in a static field which we 
could grab like this:
   
   ```    
       Class<?> bitsClass = Class.forName("java.nio.Bits");
       Field maxMemField = bitsClass.getDeclaredField("MAX_MEMORY");
       maxMemField.setAccessible(true);
       long maxMem = (Long) maxMemField.get(null);
   ```
   
   However, this will complain loudly on stderr with something like:
   ```
   WARNING: An illegal reflective access operation has occurred
   WARNING: Illegal reflective access by me.clintropolis.sandbox.mem.Main 
(file:/Users/clint/workspace/clintropolis/sandbox/target/classes/) to field 
java.nio.Bits.MAX_MEMORY
   WARNING: Please consider reporting this to the maintainers of 
me.clintropolis.sandbox.mem.Main
   WARNING: Use --illegal-access=warn to enable warnings of further illegal 
reflective access operations
   WARNING: All illegal access operations will be denied in a future release
   ```
   
   The 2nd way involves directly using `jdk.internal.misc.VM` like we were 
doing for `sun.misc.VM` something like:
   ```
       Class<?> vmClass = Class.forName("jdk.internal.misc.VM");
       Object maxDirectMemoryObj = 
vmClass.getMethod("maxDirectMemory").invoke(null);
   
       if (maxDirectMemoryObj == null || !(maxDirectMemoryObj instanceof 
Number)) {
         throw new UOE("Cannot determine maxDirectMemory from [%s]", 
maxDirectMemoryObj);
       } else {
         return ((Number) maxDirectMemoryObj).longValue();
       }
   ```
   and adding:
   ```
   --add-exports java.base/jdk.internal.misc=ALL-UNNAMED
   ```
   to the `java` command-line when running (or stuff in jvm.config?). If this 
is not added, it will explode violently with:
   ```
   Exception in thread "main" java.lang.IllegalAccessException: class 
me.clintropolis.sandbox.mem.Main cannot access class jdk.internal.misc.VM (in 
module java.base) because module java.base does not export jdk.internal.misc to 
unnamed module @2f7c7260
        at 
java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
        at 
java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
        at java.base/java.lang.reflect.Method.invoke(Method.java:558)
        at me.clintropolis.sandbox.mem.Main.main(Main.java:17)
   ```
   
   Other approaches I've seen: [Netty has some crazy bit about trying to pull 
it from the java command-line 
options](https://github.com/netty/netty/blob/4.1/common/src/main/java/io/netty/util/internal/PlatformDependent.java#L1035)
 to parse if the user has set `-XX:MaxDirectMemorySize` and try to use that if 
it can't get the information from `sun.misc.VM`, but i'm unsure if that is 
reasonable to do here. 
   
   Personally, I don't really understand why the java developers don't think it 
necessary to provide a friendly way to expose this information, but it is what 
it is. 
   
   I don't know if we want to pursue either of these approaches, just wanted to 
bring it up for discussion. All this said, it looks to me like [the jdk itself 
defaults max directMemory to 
`Runtime.getRuntime().maxMemory()`](https://github.com/AdoptOpenJDK/openjdk-jdk12u/blob/master/src/java.base/share/classes/jdk/internal/misc/VM.java#L208)
 if `-XX:MaxDirectMemorySize` is not set, so it doesn't seem so unreasonable to 
size off of that... 
   
   Regardless, thanks for working on this stuff @xvrl!
   
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to