1 package com.sun.nio.ch; 2 3 import jdk.internal.ref.Cleaner; 4 import sun.nio.ch.DirectBuffer; 5 6 import java.nio.ByteBuffer; 7 import java.nio.channels.FileChannel; 8 import java.security.Permission; 9 10 /** 11 * A utility to deallocate native memory retained by direct byte buffers. 12 * 13 * @since 9 14 */ 15 public final class DirectBufferDeallocator { 16 17 private static final Permission PERMISSION = 18 new RuntimePermission("directBufferDeallocatorAccess"); 19 20 /** 21 * Constructs a {@code DirectBufferDeallocator} which can be used to 22 * {@link #deallocate} direct memory retained by 23 * {@link ByteBuffer#isDirect() direct} {@code ByteBuffer}s. 24 * <p> First, if there is a security manager, its {@code checkPermission} 25 * method is called with a {@link java.lang.RuntimePermission} with target 26 * {@code "directBufferDeallocatorAccess"}. This may result in a security 27 * exception. 28 * <p> The returned {@code DirectBufferDeallocator} object should be carefully 29 * guarded by the caller, since it can be used to deallocate native memory 30 * used by direct buffers while access to it is still being performed 31 * and consequently jeopardise the stability of the VM process as a whole. 32 * 33 * @return the DirectBufferDeallocator 34 * @throws SecurityException if a security manager exists and its 35 * {@code checkPermission} method doesn't allow 36 * access to the RuntimePermission 37 * "directBufferDeallocatorAccess". 38 */ 39 public DirectBufferDeallocator() { 40 SecurityManager security = System.getSecurityManager(); 41 if (security != null) 42 security.checkPermission(PERMISSION); 43 } 44 45 /** 46 * If given {@code buffer} is a {@link ByteBuffer#isDirect() direct} 47 * {@code ByteBuffer} obtained by invoking 48 * {@link ByteBuffer#allocateDirect} or {@link FileChannel#map} methods, 49 * native memory retained by it is deallocated or unmapped. 50 * Otherwise if given {@code buffer} is not a direct buffer or has been 51 * obtained by {@link ByteBuffer#duplicate() duplicating} or 52 * {@link ByteBuffer#slice(int, int) slicing} a direct buffer, 53 * then this method does nothing. 54 * 55 * @param buffer a {@code ByteBuffer} which's native memory is to be 56 * deallocated. 57 */ 58 public void deallocate(ByteBuffer buffer) { 59 if (buffer.isDirect()) { 60 Cleaner cleaner = ((DirectBuffer) buffer).cleaner(); 61 if (cleaner != null) { 62 cleaner.clean(); 63 } 64 } 65 } 66 }