2626import org .slf4j .LoggerFactory ;
2727
2828/**
29- * A Helper class which use reflections to clean up DirectBuffer. It's implemented for
30- * better compatibility with both java8 and java9+, because the Cleaner class is moved to
31- * another place since java9+.
32- * <p>
33- * Strongly inspired by:
34- * https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/buf/ByteBufferUtils.java
29+ * A helper class which uses {@code sun.misc.Unsafe.invokeCleaner} to explicitly free
30+ * direct ByteBuffers.
3531 */
3632public class CleanUtil {
3733 private static final Logger logger = LoggerFactory .getLogger (CleanUtil .class );
3834
3935 private static final Object unsafe ;
40- private static final Method cleanerMethod ;
41- private static final Method cleanMethod ;
4236 private static final Method invokeCleanerMethod ;
4337
44- private static final int majorVersion =
45- Integer .parseInt (System .getProperty ("java.version" ).split ("\\ D+" )[0 ]);
46-
4738 static {
4839 final ByteBuffer tempBuffer = ByteBuffer .allocateDirect (0 );
49- Method cleanerMethodLocal = null ;
50- Method cleanMethodLocal = null ;
5140 Object unsafeLocal = null ;
5241 Method invokeCleanerMethodLocal = null ;
53- if (majorVersion >= 9 ) {
54- try {
55- final Class <?> clazz = Class .forName ("sun.misc.Unsafe" );
56- final Field theUnsafe = clazz .getDeclaredField ("theUnsafe" );
57- theUnsafe .setAccessible (true );
58- unsafeLocal = theUnsafe .get (null );
59- invokeCleanerMethodLocal = clazz .getMethod ("invokeCleaner" , ByteBuffer .class );
60- invokeCleanerMethodLocal .invoke (unsafeLocal , tempBuffer );
61- } catch (IllegalAccessException
62- | IllegalArgumentException
63- | InvocationTargetException
64- | NoSuchMethodException
65- | SecurityException
66- | ClassNotFoundException
67- | NoSuchFieldException e ) {
68- logger .warn ("Cannot use direct ByteBuffer cleaner, memory leaking may occur" , e );
69- unsafeLocal = null ;
70- invokeCleanerMethodLocal = null ;
71- }
72- } else {
73- try {
74- cleanerMethodLocal = tempBuffer .getClass ().getMethod ("cleaner" );
75- cleanerMethodLocal .setAccessible (true );
76- final Object cleanerObject = cleanerMethodLocal .invoke (tempBuffer );
77- cleanMethodLocal = cleanerObject .getClass ().getMethod ("clean" );
78- cleanMethodLocal .invoke (cleanerObject );
79- } catch (NoSuchMethodException
80- | SecurityException
81- | IllegalAccessException
82- | IllegalArgumentException
83- | InvocationTargetException e ) {
84- logger .warn ("Cannot use direct ByteBuffer cleaner, memory leaking may occur" , e );
85- cleanerMethodLocal = null ;
86- cleanMethodLocal = null ;
87- }
42+ try {
43+ final Class <?> clazz = Class .forName ("sun.misc.Unsafe" );
44+ final Field theUnsafe = clazz .getDeclaredField ("theUnsafe" );
45+ theUnsafe .setAccessible (true );
46+ unsafeLocal = theUnsafe .get (null );
47+ invokeCleanerMethodLocal = clazz .getMethod ("invokeCleaner" , ByteBuffer .class );
48+ invokeCleanerMethodLocal .invoke (unsafeLocal , tempBuffer );
49+ } catch (IllegalAccessException
50+ | IllegalArgumentException
51+ | InvocationTargetException
52+ | NoSuchMethodException
53+ | SecurityException
54+ | ClassNotFoundException
55+ | NoSuchFieldException e ) {
56+ logger .warn ("Cannot use direct ByteBuffer cleaner, memory leaking may occur" , e );
57+ unsafeLocal = null ;
58+ invokeCleanerMethodLocal = null ;
8859 }
89- cleanerMethod = cleanerMethodLocal ;
90- cleanMethod = cleanMethodLocal ;
9160 unsafe = unsafeLocal ;
9261 invokeCleanerMethod = invokeCleanerMethodLocal ;
9362 }
@@ -97,16 +66,7 @@ private CleanUtil() {
9766 }
9867
9968 public static void cleanDirectBuffer (ByteBuffer buf ) {
100- if (cleanMethod != null ) {
101- try {
102- cleanMethod .invoke (cleanerMethod .invoke (buf ));
103- } catch (IllegalAccessException
104- | IllegalArgumentException
105- | InvocationTargetException
106- | SecurityException e ) {
107- logger .warn ("Error while cleaning up the DirectBuffer" , e );
108- }
109- } else if (invokeCleanerMethod != null ) {
69+ if (invokeCleanerMethod != null ) {
11070 try {
11171 invokeCleanerMethod .invoke (unsafe , buf );
11272 } catch (IllegalAccessException
0 commit comments