< prev index next >

src/java.base/share/classes/sun/nio/ch/Util.java

Print this page
rev 50167 : 8202788: Explicitly reclaim cached thread-local direct buffers at thread exit
Reviewed-by:

@@ -33,10 +33,11 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Set;
+import jdk.internal.misc.JdkThreadLocal;
 import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 import java.io.IOException;
 
 public class Util {

@@ -49,16 +50,21 @@
     // The max size allowed for a cached temp buffer, in bytes
     private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
 
     // Per-thread cache of temporary direct buffers
     private static ThreadLocal<BufferCache> bufferCache =
-        new ThreadLocal<BufferCache>()
+        new JdkThreadLocal<>()
     {
         @Override
         protected BufferCache initialValue() {
             return new BufferCache();
         }
+
+        @Override
+        protected void threadTerminated(BufferCache cache) {
+            cache.freeAll();
+        }
     };
 
     /**
      * Returns the max size allowed for a cached temp buffers, in
      * bytes. It defaults to Long.MAX_VALUE. It can be set with the

@@ -203,10 +209,29 @@
             buffers[start] = null;
             start = next(start);
             count--;
             return buf;
         }
+
+        void freeAll() {
+            if (isEmpty()) {
+                return;
+            }
+
+            for (int i = 0; i < buffers.length; i += 1) {
+                final ByteBuffer buf = buffers[i];
+                if (buf == null) {
+                    continue;
+                }
+
+                free(buf);
+                // just in case
+                buffers[i] = null;
+            }
+            // just in case
+            count = 0;
+        }
     }
 
     /**
      * Returns a temporary buffer of at least the given size
      */
< prev index next >