Repository: netty/netty
Issue: [feautre request] Add a util method to get maxDirectMemory
Labels: feature
discussion

Netty's `PlatformDependent.maxDirectMemory()` is powerful and general.
In other project, we want to read the `maxDirectMemory` too. 
But we can't directly use `PlatformDependent.maxDirectMemory()` , because it will wrong if user set `io.netty.maxDirectMemory` greater than zero. 
Instead of copy and paste netty's code(Under Apache License), I want a UtilityClass to get `PlatformDependent.maxDirectMemory0` result.

I am not very familiar with netty code,  I can work on this under guides.

Thanks for your help.

Issue comments:
@chrisvest what do you think... Not sure we want to expose just another public method. I guess we could do it tho
@normanmaurer it's -1  to me, but I would like to understand why @Shoothzj need it/the exact use case
@franz1981 It's started with https://github.com/apache/bookkeeper/pull/2989 when locating a `Out of DirectMemory Error`. We found the the maxDirectMemory read by bookkeeper is not correct with *huawei jdk 11*, but the result read by netty is correct.
I want to improve the maxDirectMemory readed by bookkeepe but without the `io.netty.maxDirectMemory`.

Please point out if I didn't make it clear. My English is not good. Thanks
cc @normanmaurer 
wdyt @normanmaurer ?

I know that Netty's `OutOfDirectMemoryError` throwing condition is tied with the Netty's notion of max direct memory, hence if we allow the exception to leak ie `OutOfDirectMemoryError` is public, maybe makes sense our limits to leak as well. 
Another option for @Shoothzj could be to react to such information (if structured to be used) while the limit is reached, but we need to change `OutOfDirectMemoryError` in order to expose exception fields that represent our limits/current values ie 
`requestedCapacity, usedCapacity, DIRECT_MEMORY_LIMIT as max allowed capacity`
@normanmaurer @franz1981 I don't see a big problem in exposing `maxDirectMemory0` as `estimateMaxDirectMemory`.
technically it wouldn't even be part of the public API, last I recall PlatformDependent is in the "internal" package, that said could annotate it as UnstableApi?
Let's wait what @normanmaurer answer on this, but I like both @chrisvest and @johnou answers 

Pull request review comments:

Patch that resolved the issue:
diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java
index a116da2451f..d6b140988b4 100644
--- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java
+++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java
@@ -89,7 +89,7 @@ public final class PlatformDependent {
 
     private static final Throwable UNSAFE_UNAVAILABILITY_CAUSE = unsafeUnavailabilityCause0();
     private static final boolean DIRECT_BUFFER_PREFERRED;
-    private static final long MAX_DIRECT_MEMORY = maxDirectMemory0();
+    private static final long MAX_DIRECT_MEMORY = estimateMaxDirectMemory();
 
     private static final int MPSC_CHUNK_SIZE =  1024;
     private static final int MIN_MAX_MPSC_CAPACITY =  MPSC_CHUNK_SIZE * 2;
@@ -1147,7 +1147,16 @@ private static boolean isIkvmDotNet0() {
         return vmName.equals("IKVM.NET");
     }
 
-    private static long maxDirectMemory0() {
+    /**
+     * Compute an estimate of the maximum amount of direct memory available to this JVM.
+     * <p>
+     * The computation is not cached, so you probably want to use {@link #maxDirectMemory()} instead.
+     * <p>
+     * This will produce debug log output when called.
+     *
+     * @return The estimated max direct memory, in bytes.
+     */
+    public static long estimateMaxDirectMemory() {
         long maxDirectMemory = 0;
 
         ClassLoader systemClassLoader = null;


Test patch: