Open franz1981 opened 7 months ago
@zakkak @cescoffier
Hum, we cannot really recommend using --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
.
I agree we should only resolve to opening core modules only if strictly necessary.
To me is fine to:
-Dio.netty.tryReflectionSetAccessible=true --add-opens=java.base/java.nio=ALL-UNNAMED
and see if it bring evident benefits (on native image)The issue related zeroing of heap buffers (i.e. byte[]) can be verified (in native image as well) by enabling debug/trace logging and search for these log messages: https://github.com/netty/netty/blob/afb475dabd5ca9eaa94ccf07f0ecd8431db008ba/common/src/main/java/io/netty/util/internal/PlatformDependent0.java#L507-L517
@zakkak
We would need alternatives to enable these options without requiring an add-open.
The alternative for the one impacting SSL is already in; by having SSL heap buffer pooling we don't need to care about allocate uninitialized arrays, cause we won't allocate them anymore 😁 For the cleaner one, I have to think 🤔
Description
Currently there are (after the introduction of Java modules), few Netty features, which are not enabled because the "right" JVM args are not present by default on quarkus applications:
Cleaner
s: this is used on off-heap pooled arena(s) backed NIOByteBuffer
s. It can be enabled adding-Dio.netty.tryReflectionSetAccessible=true --add-opens=java.base/java.nio=ALL-UNNAMED
to the JVM args.byte[]
without zeroing them, using the "hidden" feature explained at https://shipilev.net/jvm/anatomy-quarks/7-initialization-costs/#_experiment. It can be enabled via-Dio.netty.tryReflectionSetAccessible=true --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
I'm not proposing to add both, but I think is important to be aware that these features are not available in the current default configuration.
The first problem (related the cleaner option) is pretty important, because:
OutOfDirectMemory
(which is not "yay", the opposite: see https://github.com/openjdk/jdk/blob/jdk-21%2B35/src/java.base/share/classes/java/nio/Bits.java#L145-L178 how ugly can go!)ByteBuffer
s allocations are tracked separately by OpenJDK, while the Netty direct allocations would useUnsafe::allocateMemory
, instead, and its limit are enforced by Netty, instead. This means that the TOTAL memory required (in theory) to a container is: *3max java heap**(!!!! ie heap + direct NIO memory limit + Netty direct memory limit). Additionally, there won't be any JVM metrics (maybe just native memory tracking AFAIK), which can report the total number of allocated direct memory (including the one from Netty, via Unsafe). Thanks to @alesj we can still use the Netty memory metrics, anyway, for this purpose.So, why this second option could be appealing?
ByteBuffer
s won't contain anyCleaner
saving some memoryImplementation ideas
Configured the proposed option by default