< 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 >