1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.internal;
17
18 import io.netty.util.internal.logging.InternalLogger;
19 import io.netty.util.internal.logging.InternalLoggerFactory;
20
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.nio.ByteBuffer;
24
25
26
27
28
29
30
31
32 final class CleanerJava6 implements Cleaner {
33 private static final long CLEANER_FIELD_OFFSET;
34 private static final Method CLEAN_METHOD;
35
36 private static final InternalLogger logger = InternalLoggerFactory.getInstance(CleanerJava6.class);
37
38 static {
39 long fieldOffset = -1;
40 Method clean = null;
41 Throwable error = null;
42 if (PlatformDependent0.hasUnsafe()) {
43 ByteBuffer direct = ByteBuffer.allocateDirect(1);
44 try {
45 Field cleanerField = direct.getClass().getDeclaredField("cleaner");
46 fieldOffset = PlatformDependent0.objectFieldOffset(cleanerField);
47 Object cleaner = PlatformDependent0.getObject(direct, fieldOffset);
48 clean = cleaner.getClass().getDeclaredMethod("clean");
49 clean.invoke(cleaner);
50 } catch (Throwable t) {
51
52 fieldOffset = -1;
53 clean = null;
54 error = t;
55 }
56 } else {
57 error = new UnsupportedOperationException("sun.misc.Unsafe unavailable");
58 }
59 if (error == null) {
60 logger.debug("java.nio.ByteBuffer.cleaner(): available");
61 } else {
62 logger.debug("java.nio.ByteBuffer.cleaner(): unavailable", error);
63 }
64 CLEANER_FIELD_OFFSET = fieldOffset;
65 CLEAN_METHOD = clean;
66 }
67
68 static boolean isSupported() {
69 return CLEANER_FIELD_OFFSET != -1;
70 }
71
72 @Override
73 public void freeDirectBuffer(ByteBuffer buffer) {
74 if (!buffer.isDirect()) {
75 return;
76 }
77 try {
78 Object cleaner = PlatformDependent0.getObject(buffer, CLEANER_FIELD_OFFSET);
79 if (cleaner != null) {
80 CLEAN_METHOD.invoke(cleaner);
81 }
82 } catch (Throwable cause) {
83 PlatformDependent0.throwException(cause);
84 }
85 }
86 }