< prev index next >
src/java.base/share/classes/java/nio/Bits.java
Print this page
rev 15227 : imported patch vm_api
*** 129,174 ****
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;
}
! }
// 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 {
--- 129,189 ----
if (tryReserveMemory(size, cap)) {
return;
}
final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
+ boolean interrupted = false;
+ try {
! // Retry allocation until success or there are no more
! // references (including Cleaners that might free direct
! // buffer memory) to process and allocation still fails.
! boolean refprocActive;
! do {
! try {
! refprocActive = jlra.waitForReferenceProcessing();
! } catch (InterruptedException e) {
! // Defer interrupts and keep trying.
! interrupted = true;
! refprocActive = true;
! }
if (tryReserveMemory(size, cap)) {
return;
}
! } while (refprocActive);
// trigger VM's Reference processing
System.gc();
! // A retry loop with exponential back-off delays.
! // Sometimes it would suffice to give up once reference
! // processing is complete. But if there are many threads
! // competing for memory, this gives more opportunities for
! // any given thread to make progress. In particular, this
! // seems to be enough for a stress test like
! // DirectBufferAllocTest to (usually) succeed, while
! // without it that test likely fails. Since failure here
! // ends in OOME, there's no need to hurry.
long sleepTime = 1;
int sleeps = 0;
while (true) {
if (tryReserveMemory(size, cap)) {
return;
}
if (sleeps >= MAX_SLEEPS) {
break;
}
try {
+ if (!jlra.waitForReferenceProcessing()) {
Thread.sleep(sleepTime);
sleepTime <<= 1;
sleeps++;
+ }
} catch (InterruptedException e) {
interrupted = true;
}
}
// no luck
throw new OutOfMemoryError("Direct buffer memory");
} finally {
< prev index next >