8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.nio; 27 28 import java.util.concurrent.atomic.AtomicLong; 29 30 import jdk.internal.misc.JavaNioAccess; 31 import jdk.internal.misc.JavaLangRefAccess; 32 import jdk.internal.misc.SharedSecrets; 33 import jdk.internal.misc.Unsafe; 34 import jdk.internal.misc.VM; 35 36 /** 37 * Access to bits, native and otherwise. 38 */ 39 40 class Bits { // package-private 41 42 private Bits() { } 43 44 45 // -- Swapping -- 46 47 static short swap(short x) { 48 return Short.reverseBytes(x); 49 } 50 51 static char swap(char x) { 52 return Character.reverseBytes(x); 53 } 54 586 } 587 588 private static boolean unaligned = unsafe.unalignedAccess(); 589 590 static boolean unaligned() { 591 return unaligned; 592 } 593 594 595 // -- Direct memory management -- 596 597 // A user-settable upper limit on the maximum amount of allocatable 598 // direct buffer memory. This value may be changed during VM 599 // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". 600 private static volatile long maxMemory = VM.maxDirectMemory(); 601 private static final AtomicLong reservedMemory = new AtomicLong(); 602 private static final AtomicLong totalCapacity = new AtomicLong(); 603 private static final AtomicLong count = new AtomicLong(); 604 private static volatile boolean memoryLimitSet; 605 606 // max. number of sleeps during try-reserving with exponentially 607 // increasing delay before throwing OutOfMemoryError: 608 // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s) 609 // which means that OOME will be thrown after 0.5 s of trying 610 private static final int MAX_SLEEPS = 9; 611 612 // These methods should be called whenever direct memory is allocated or 613 // freed. They allow the user to control the amount of direct memory 614 // which a process may access. All sizes are specified in bytes. 615 static void reserveMemory(long size, int cap) { 616 617 if (!memoryLimitSet && VM.initLevel() >= 1) { 618 maxMemory = VM.maxDirectMemory(); 619 memoryLimitSet = true; 620 } 621 622 // optimist! 623 if (tryReserveMemory(size, cap)) { 624 return; 625 } 626 627 final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess(); 628 629 // retry while helping enqueue pending Reference objects 630 // which includes executing pending Cleaner(s) which includes 631 // Cleaner(s) that free direct buffer memory 632 while (jlra.tryHandlePendingReference()) { 633 if (tryReserveMemory(size, cap)) { 634 return; 635 } 636 } 637 638 // trigger VM's Reference processing 639 System.gc(); 640 641 // a retry loop with exponential back-off delays 642 // (this gives VM some time to do it's job) 643 boolean interrupted = false; 644 try { 645 long sleepTime = 1; 646 int sleeps = 0; 647 while (true) { 648 if (tryReserveMemory(size, cap)) { 649 return; 650 } 651 if (sleeps >= MAX_SLEEPS) { 652 break; 653 } 654 if (!jlra.tryHandlePendingReference()) { 655 try { 656 Thread.sleep(sleepTime); 657 sleepTime <<= 1; 658 sleeps++; 659 } catch (InterruptedException e) { 660 interrupted = true; 661 } 662 } 663 } 664 665 // no luck 666 throw new OutOfMemoryError("Direct buffer memory"); 667 668 } finally { 669 if (interrupted) { 670 // don't swallow interrupts 671 Thread.currentThread().interrupt(); 672 } 673 } 674 } 675 676 private static boolean tryReserveMemory(long size, int cap) { 677 678 // -XX:MaxDirectMemorySize limits the total capacity rather than the 679 // actual memory usage, which will differ when buffers are page 680 // aligned. 681 long totalCap; 682 while (cap <= maxMemory - (totalCap = totalCapacity.get())) { 683 if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) { 684 reservedMemory.addAndGet(size); 685 count.incrementAndGet(); 686 return true; 687 } 688 } 689 690 return false; 691 } 692 | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.nio; 27 28 import jdk.internal.misc.JavaNioAccess; 29 import jdk.internal.misc.SharedSecrets; 30 import jdk.internal.misc.Unsafe; 31 import jdk.internal.misc.VM; 32 import jdk.internal.ref.CleanerFactory; 33 34 import java.util.concurrent.atomic.AtomicLong; 35 import java.util.function.BooleanSupplier; 36 37 /** 38 * Access to bits, native and otherwise. 39 */ 40 41 class Bits { // package-private 42 43 private Bits() { } 44 45 46 // -- Swapping -- 47 48 static short swap(short x) { 49 return Short.reverseBytes(x); 50 } 51 52 static char swap(char x) { 53 return Character.reverseBytes(x); 54 } 55 587 } 588 589 private static boolean unaligned = unsafe.unalignedAccess(); 590 591 static boolean unaligned() { 592 return unaligned; 593 } 594 595 596 // -- Direct memory management -- 597 598 // A user-settable upper limit on the maximum amount of allocatable 599 // direct buffer memory. This value may be changed during VM 600 // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". 601 private static volatile long maxMemory = VM.maxDirectMemory(); 602 private static final AtomicLong reservedMemory = new AtomicLong(); 603 private static final AtomicLong totalCapacity = new AtomicLong(); 604 private static final AtomicLong count = new AtomicLong(); 605 private static volatile boolean memoryLimitSet; 606 607 // These methods should be called whenever direct memory is allocated or 608 // freed. They allow the user to control the amount of direct memory 609 // which a process may access. All sizes are specified in bytes. 610 static void reserveMemory(long size, int cap) { 611 612 if (!memoryLimitSet && VM.initLevel() >= 1) { 613 maxMemory = VM.maxDirectMemory(); 614 memoryLimitSet = true; 615 } 616 617 if (!CleanerFactory.dbbCleaner().retryWhileHelpingClean( 618 new BooleanSupplier() { 619 @Override 620 public boolean getAsBoolean() { 621 return tryReserveMemory(size, cap); 622 } 623 })) { 624 // no luck 625 throw new OutOfMemoryError("Direct buffer memory"); 626 } 627 } 628 629 private static boolean tryReserveMemory(long size, int cap) { 630 631 // -XX:MaxDirectMemorySize limits the total capacity rather than the 632 // actual memory usage, which will differ when buffers are page 633 // aligned. 634 long totalCap; 635 while (cap <= maxMemory - (totalCap = totalCapacity.get())) { 636 if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) { 637 reservedMemory.addAndGet(size); 638 count.incrementAndGet(); 639 return true; 640 } 641 } 642 643 return false; 644 } 645 |