CleanerJava24Linker Class — netty Architecture
Architecture documentation for the CleanerJava24Linker class in CleanerJava24Linker.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD 0c08734e_1658_4777_76f5_6b6460f4d613["CleanerJava24Linker"] 04dd755a_bbac_35e6_9950_f61de6d82a81["CleanerJava24Linker.java"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|defined in| 04dd755a_bbac_35e6_9950_f61de6d82a81 b94ea4fa_d4e1_cf89_a47c_d51ac16c6661["isSupported()"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|method| b94ea4fa_d4e1_cf89_a47c_d51ac16c6661 65531363_523d_b5dd_924f_8397afa410b0["CleanableDirectBuffer()"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|method| 65531363_523d_b5dd_924f_8397afa410b0 ebd05de7_0269_7e2c_73c6_39149ca749b6["freeDirectBuffer()"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|method| ebd05de7_0269_7e2c_73c6_39149ca749b6 add871eb_c3ef_e875_fa27_a4789f284655["malloc()"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|method| add871eb_c3ef_e875_fa27_a4789f284655 3017c0a9_56e5_6be2_057b_82f345655d57["free()"] 0c08734e_1658_4777_76f5_6b6460f4d613 -->|method| 3017c0a9_56e5_6be2_057b_82f345655d57
Relationship Graph
Source Code
common/src/main/java/io/netty/util/internal/CleanerJava24Linker.java lines 28–269
public class CleanerJava24Linker implements Cleaner {
private static final InternalLogger logger;
private static final MethodHandle INVOKE_MALLOC;
private static final MethodHandle INVOKE_CREATE_BYTEBUFFER;
private static final MethodHandle INVOKE_FREE;
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 CleanerJava24Linker 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 24 or greater, where warnings about Unsafe
// memory access operations start to appear.
// The following JDK bugs do NOT affect our implementation because the memory segments we
// create are associated with the GLOBAL_SESSION:
// - https://bugs.openjdk.org/browse/JDK-8357145
// - https://bugs.openjdk.org/browse/JDK-8357268
suitableJavaVersion = PlatformDependent0.javaVersion() >= 24;
logger = InternalLoggerFactory.getInstance(CleanerJava24Linker.class);
}
MethodHandle mallocMethod;
MethodHandle wrapMethod;
MethodHandle freeMethod;
Throwable error;
if (suitableJavaVersion) {
try {
// First, we need to check if we have access to "restricted" methods through the Java Module system.
MethodHandles.Lookup lookup = MethodHandles.lookup();
Class<?> moduleCls = Class.forName("java.lang.Module");
MethodHandle getModule = lookup.findVirtual(
Class.class, "getModule", methodType(moduleCls));
MethodHandle isNativeAccessEnabledModule = lookup.findVirtual(
moduleCls, "isNativeAccessEnabled", methodType(boolean.class));
MethodHandle isNativeAccessEnabledForClass = MethodHandles.filterArguments(
isNativeAccessEnabledModule, 0, getModule);
boolean isNativeAccessEnabled =
(boolean) isNativeAccessEnabledForClass.invokeExact(CleanerJava24Linker.class);
if (!isNativeAccessEnabled) {
throw new UnsupportedOperationException(
"Native access (restricted methods) is not enabled for the io.netty.common module.");
}
// Second, we need to check the size of a pointer address. For simplicity, we'd like to assume the size
// of an address is the same as a Java long. So effectively, we're only enabled on 64-bit platforms.
Class<?> memoryLayoutCls = Class.forName("java.lang.foreign.MemoryLayout");
Class<?> memoryLayoutArrayCls = Class.forName("[Ljava.lang.foreign.MemoryLayout;");
Class<?> valueLayoutCls = Class.forName("java.lang.foreign.ValueLayout");
Class<?> valueLayoutAddressCls = Class.forName("java.lang.foreign.AddressLayout");
MethodHandle addressLayoutGetter = lookup.findStaticGetter(
valueLayoutCls, "ADDRESS", valueLayoutAddressCls);
MethodHandle byteSize = lookup.findVirtual(valueLayoutAddressCls, "byteSize", methodType(long.class));
MethodHandle byteSizeOfAddress = MethodHandles.foldArguments(byteSize, addressLayoutGetter);
long addressSize = (long) byteSizeOfAddress.invokeExact();
if (addressSize != Long.BYTES) {
throw new UnsupportedOperationException(
"Linking to malloc and free is only supported on 64-bit platforms.");
}
// Finally, we create three method handles, for malloc, free, and for wrapping an address in a
// ByteBuffer. Effectively, we need the equivalent of these three code snippets:
//
// MemorySegment mallocPtr = Linker.nativeLinker().defaultLookup().find("malloc").get();
// MethodHandle malloc = Linker.nativeLinker().downcallHandle(
// mallocPtr, FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG));
//
// MemorySegment freePtr = Linker.nativeLinker().defaultLookup().find("free").get();
// MethodHandle free = Linker.nativeLinker().downcallHandle(
// freePtr, FunctionDescriptor.ofVoid(ValueLayout.JAVA_LONG));
//
Source
Frequently Asked Questions
What is the CleanerJava24Linker class?
CleanerJava24Linker is a class in the netty codebase, defined in common/src/main/java/io/netty/util/internal/CleanerJava24Linker.java.
Where is CleanerJava24Linker defined?
CleanerJava24Linker is defined in common/src/main/java/io/netty/util/internal/CleanerJava24Linker.java at line 28.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free