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