< prev index next >

src/java.base/share/classes/java/nio/Bits.java

Print this page

        

@@ -23,17 +23,18 @@
  * questions.
  */
 
 package java.nio;
 
-import java.util.concurrent.atomic.AtomicLong;
-
 import jdk.internal.misc.JavaNioAccess;
-import jdk.internal.misc.JavaLangRefAccess;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.Unsafe;
 import jdk.internal.misc.VM;
+import jdk.internal.ref.CleanerFactory;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BooleanSupplier;
 
 /**
  * Access to bits, native and otherwise.
  */
 

@@ -601,77 +602,29 @@
     private static final AtomicLong reservedMemory = new AtomicLong();
     private static final AtomicLong totalCapacity = new AtomicLong();
     private static final AtomicLong count = new AtomicLong();
     private static volatile boolean memoryLimitSet;
 
-    // max. number of sleeps during try-reserving with exponentially
-    // increasing delay before throwing OutOfMemoryError:
-    // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
-    // which means that OOME will be thrown after 0.5 s of trying
-    private static final int MAX_SLEEPS = 9;
-
     // These methods should be called whenever direct memory is allocated or
     // freed.  They allow the user to control the amount of direct memory
     // which a process may access.  All sizes are specified in bytes.
     static void reserveMemory(long size, int cap) {
 
         if (!memoryLimitSet && VM.initLevel() >= 1) {
             maxMemory = VM.maxDirectMemory();
             memoryLimitSet = true;
         }
 
-        // optimist!
-        if (tryReserveMemory(size, cap)) {
-            return;
-        }
-
-        final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
-
-        // retry while helping enqueue pending Reference objects
-        // which includes executing pending Cleaner(s) which includes
-        // Cleaner(s) that free direct buffer memory
-        while (jlra.tryHandlePendingReference()) {
-            if (tryReserveMemory(size, cap)) {
-                return;
-            }
+        if (!CleanerFactory.cleaner().retryWhileHelpingClean(
+            new BooleanSupplier() {
+                @Override
+                public boolean getAsBoolean() {
+                    return tryReserveMemory(size, cap);
         }
-
-        // trigger VM's Reference processing
-        System.gc();
-
-        // a retry loop with exponential back-off delays
-        // (this gives VM some time to do it's job)
-        boolean interrupted = false;
-        try {
-            long sleepTime = 1;
-            int sleeps = 0;
-            while (true) {
-                if (tryReserveMemory(size, cap)) {
-                    return;
-                }
-                if (sleeps >= MAX_SLEEPS) {
-                    break;
-                }
-                if (!jlra.tryHandlePendingReference()) {
-                    try {
-                        Thread.sleep(sleepTime);
-                        sleepTime <<= 1;
-                        sleeps++;
-                    } catch (InterruptedException e) {
-                        interrupted = true;
-                    }
-                }
-            }
-
+            })) {
             // no luck
             throw new OutOfMemoryError("Direct buffer memory");
-
-        } finally {
-            if (interrupted) {
-                // don't swallow interrupts
-                Thread.currentThread().interrupt();
-            }
         }
     }
 
     private static boolean tryReserveMemory(long size, int cap) {
 
< prev index next >