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 df9b52d87c..67f29e83f0 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -228,7 +228,11 @@ public final class PlatformDependent { */ public static void freeDirectBuffer(ByteBuffer buffer) { if (buffer.isDirect()) { - PlatformDependent0.freeDirectBuffer(buffer); + if (hasUnsafe()) { + PlatformDependent0.freeDirectBufferUnsafe(buffer); + } else { + PlatformDependent0.freeDirectBuffer(buffer); + } } } diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java index a9b6a65648..5eaf573721 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -37,6 +37,7 @@ final class PlatformDependent0 { private static final long CLEANER_FIELD_OFFSET; private static final long ADDRESS_FIELD_OFFSET; + private static final Field CLEANER_FIELD; /** * {@code true} if and only if the platform supports unaligned access. @@ -56,6 +57,7 @@ final class PlatformDependent0 { } catch (Throwable t) { cleanerField = null; } + CLEANER_FIELD = cleanerField; logger.debug("java.nio.ByteBuffer.cleaner: {}", cleanerField != null? "available" : "unavailable"); Field addressField; @@ -145,7 +147,7 @@ final class PlatformDependent0 { UNSAFE.throwException(t); } - static void freeDirectBuffer(ByteBuffer buffer) { + static void freeDirectBufferUnsafe(ByteBuffer buffer) { Cleaner cleaner; try { cleaner = (Cleaner) getObject(buffer, CLEANER_FIELD_OFFSET); @@ -159,6 +161,22 @@ final class PlatformDependent0 { } } + static void freeDirectBuffer(ByteBuffer buffer) { + if (CLEANER_FIELD == null) { + return; + } + try { + Cleaner cleaner = (Cleaner) CLEANER_FIELD.get(buffer); + if (cleaner == null) { + throw new IllegalArgumentException( + "attempted to deallocate the buffer which was allocated via JNIEnv->NewDirectByteBuffer()"); + } + cleaner.clean(); + } catch (Throwable t) { + // Nothing we can do here. + } + } + static long directBufferAddress(ByteBuffer buffer) { return getLong(buffer, ADDRESS_FIELD_OFFSET); }