Home / Class/ CleanerJava25 Class — netty Architecture

CleanerJava25 Class — netty Architecture

Architecture documentation for the CleanerJava25 class in CleanerJava25.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  7ab188e3_8847_b494_ece0_39be8ad2e276["CleanerJava25"]
  65e55f1e_37ee_36e5_4c41_4fe66a648def["CleanerJava25.java"]
  7ab188e3_8847_b494_ece0_39be8ad2e276 -->|defined in| 65e55f1e_37ee_36e5_4c41_4fe66a648def
  751eba07_7c52_5eae_9dc5_a33d68166a95["isSupported()"]
  7ab188e3_8847_b494_ece0_39be8ad2e276 -->|method| 751eba07_7c52_5eae_9dc5_a33d68166a95
  e255d12a_e22f_df1a_aceb_4df26362cfcd["CleanableDirectBuffer()"]
  7ab188e3_8847_b494_ece0_39be8ad2e276 -->|method| e255d12a_e22f_df1a_aceb_4df26362cfcd
  71eda40f_742e_a4f1_463b_cb43318bc270["freeDirectBuffer()"]
  7ab188e3_8847_b494_ece0_39be8ad2e276 -->|method| 71eda40f_742e_a4f1_463b_cb43318bc270

Relationship Graph

Source Code

common/src/main/java/io/netty/util/internal/CleanerJava25.java lines 31–224

final class CleanerJava25 implements Cleaner {
    private static final InternalLogger logger;

    private static final MethodHandle INVOKE_ALLOCATOR;

    static {
        boolean suitableJavaVersion;
        if (System.getProperty("org.graalvm.nativeimage.imagecode") != null) {
            // native image supports this since 25, but we don't use PlatformDependent0 here, since
            // we need to initialize CleanerJava25 at build time.
            String v = System.getProperty("java.specification.version");
            try {
                suitableJavaVersion = Integer.parseInt(v) >= 25;
            } catch (NumberFormatException e) {
                suitableJavaVersion = false;
            }
            // also need to prevent initializing the logger at build time
            logger = null;
        } else {
            // Only attempt to use MemorySegments on Java 25 or greater, because of the following JDK bugs:
            // - https://bugs.openjdk.org/browse/JDK-8357145
            // - https://bugs.openjdk.org/browse/JDK-8357268
            suitableJavaVersion = PlatformDependent0.javaVersion() >= 25;
            logger = InternalLoggerFactory.getInstance(CleanerJava25.class);
        }

        MethodHandle method;
        Throwable error;
        if (suitableJavaVersion) {
            try {
                // Here we compose and construct a MethodHandle that takes an 'int' capacity argument,
                // and produces a 'CleanableDirectBufferImpl' instance.
                // The method handle will create a new shared Arena instance, allocate a MemorySegment from it,
                // convert the MemorySegment to a ByteBuffer and a memory address, and then pass both the Arena,
                // the ByteBuffer, and the memory address to the CleanableDirectBufferImpl constructor,
                // returning the resulting object.
                //
                // Effectively, we are recreating the following the Java code through MethodHandles alone:
                //
                //    Arena arena = Arena.ofShared();
                //    MemorySegment segment = arena.allocate(size);
                //    return new CleanableDirectBufferImpl(
                //              (AutoCloseable) arena,
                //              segment.asByteBuffer(),
                //              segment.address());
                //
                // First, we need the types we'll use to set this all up.
                Class<?> arenaCls = Class.forName("java.lang.foreign.Arena");
                Class<?> memsegCls = Class.forName("java.lang.foreign.MemorySegment");
                Class<CleanableDirectBufferImpl> bufCls = CleanableDirectBufferImpl.class;
                // Acquire the private look up, so we can access the package-private 'CleanableDirectBufferImpl'
                // constructor.
                MethodHandles.Lookup lookup = MethodHandles.lookup();

                // ofShared.type() = ()Arena
                MethodHandle ofShared = lookup.findStatic(arenaCls, "ofShared", methodType(arenaCls));

                // Try to access shared Arena which might fail on GraalVM 25.0.0 if not enabled
                // See https://github.com/netty/netty/issues/15762
                Object shared = ofShared.invoke();
                ((AutoCloseable) shared).close();

                // allocate.type() = (Arena,long)MemorySegment
                MethodHandle allocate = lookup.findVirtual(arenaCls, "allocate", methodType(memsegCls, long.class));
                // asByteBuffer.type() = (MemorySegment)ByteBuffer
                MethodHandle asByteBuffer = lookup.findVirtual(memsegCls, "asByteBuffer", methodType(ByteBuffer.class));
                // address.type() = (MemorySegment)long
                MethodHandle address = lookup.findVirtual(memsegCls, "address", methodType(long.class));
                // bufClsCtor.type() = (AutoCloseable,ByteBuffer,long)CleanableDirectBufferImpl
                MethodHandle bufClsCtor = lookup.findConstructor(bufCls,
                        methodType(void.class, AutoCloseable.class, ByteBuffer.class, long.class));
                // The 'allocate' method takes a 'long' capacity, but we'll be providing an 'int'.
                // Explicitly cast the 'long' to 'int' so we can use 'invokeExact'.
                // allocateInt.type() = (Arena,int)MemorySegment
                MethodHandle allocateInt = MethodHandles.explicitCastArguments(allocate,
                        methodType(memsegCls, arenaCls, int.class));
                // Use the 'asByteBuffer' and 'address' methods as a filter, to transform the constructor into a method
                // that takes two MemorySegment arguments instead of a ByteBuffer and a long argument.
                // ctorArenaMemsegMemseg.type() = (Arena,MemorySegment,MemorySegment)CleanableDirectBufferImpl
                MethodHandle ctorArenaMemsegMemseg = MethodHandles.explicitCastArguments(
                        MethodHandles.filterArguments(bufClsCtor, 1, asByteBuffer, address),

Frequently Asked Questions

What is the CleanerJava25 class?
CleanerJava25 is a class in the netty codebase, defined in common/src/main/java/io/netty/util/internal/CleanerJava25.java.
Where is CleanerJava25 defined?
CleanerJava25 is defined in common/src/main/java/io/netty/util/internal/CleanerJava25.java at line 31.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free