1 22 package org.xsocket.datagram; 23 24 import java.lang.ref.SoftReference ; 25 import java.nio.ByteBuffer ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 import java.util.logging.Level ; 29 import java.util.logging.Logger ; 30 31 import org.xsocket.DataConverter; 32 33 34 39 class MemoryManager { 40 41 private static final Logger LOG = Logger.getLogger(MemoryManager.class.getName()); 42 43 44 private List <SoftReference <ByteBuffer >> memoryBuffer = new ArrayList <SoftReference <ByteBuffer >>(); 45 46 private boolean useDirectMemory = false; 47 private int preallocationSize = 4096; 48 49 50 56 MemoryManager(int preallocationSize, boolean useDirectMemory) { 57 this.preallocationSize = preallocationSize; 58 this.useDirectMemory = useDirectMemory; 59 } 60 61 62 67 public final synchronized int getFreeBufferSize() { 68 int size = 0; 69 for (SoftReference <ByteBuffer > bufferRef: memoryBuffer) { 70 ByteBuffer buffer = bufferRef.get(); 71 if (buffer != null) { 72 size += buffer.remaining(); 73 } 74 } 75 return size; 76 } 77 78 79 80 private void recycleMemory(ByteBuffer buffer) { 81 if (buffer.hasRemaining()) { 82 memoryBuffer.add(new SoftReference <ByteBuffer >(buffer.slice())); 83 } 84 } 85 86 87 92 public final synchronized ByteBuffer acquireMemory(int size) { 93 ByteBuffer buffer = null; 94 95 if (!memoryBuffer.isEmpty()) { 96 SoftReference <ByteBuffer > freeBuffer = memoryBuffer.remove(0); 97 buffer = freeBuffer.get(); 98 99 if (buffer != null) { 100 if (buffer.limit() < size) { 102 buffer = null; 103 } 104 } 105 } 106 107 108 if (buffer == null) { 109 int allocationSize = getPreallocationSize(); 110 if (getPreallocationSize() < allocationSize) { 111 allocationSize = size * 4; 112 } 113 114 buffer = newBuffer(size); 115 } 116 117 int savedLimit = buffer.limit(); 118 119 buffer.limit(size); 120 ByteBuffer result = buffer.slice(); 121 122 buffer.position(size); 123 buffer.limit(savedLimit); 124 ByteBuffer remaining = buffer.slice(); 125 recycleMemory(remaining); 126 127 return result; 128 } 129 130 131 136 int getPreallocationSize() { 137 return preallocationSize; 138 } 139 140 141 142 private final ByteBuffer newBuffer(int size) { 143 if (useDirectMemory) { 144 if (LOG.isLoggable(Level.FINE)) { 145 LOG.fine("allocating " + DataConverter.toFormatedBytesSize(size) + " direct memory"); 146 } 147 148 return ByteBuffer.allocateDirect(size); 149 150 } else { 151 if (LOG.isLoggable(Level.FINE)) { 152 LOG.fine("allocating " + DataConverter.toFormatedBytesSize(size) + " heap memory"); 153 } 154 155 return ByteBuffer.allocate(size); 156 } 157 } 158 } | Popular Tags |