1 22 package org.xsocket.stream.io.impl; 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 SynchronizedMemoryManager implements IMemoryManager { 40 41 private static final Logger LOG = Logger.getLogger(SynchronizedMemoryManager.class.getName()); 42 43 44 private List <SoftReference <ByteBuffer >> memoryBuffer = new ArrayList <SoftReference <ByteBuffer >>(); 45 46 private boolean useDirectMemory = false; 47 private int preallocationSize = 65536; 48 49 50 56 SynchronizedMemoryManager(int preallocationSize, boolean useDirectMemory) { 57 this.preallocationSize = preallocationSize; 58 this.useDirectMemory = useDirectMemory; 59 } 60 61 62 63 68 public final synchronized int getFreeBufferSize() { 69 int size = 0; 70 for (SoftReference <ByteBuffer > bufferRef: memoryBuffer) { 71 ByteBuffer buffer = bufferRef.get(); 72 if (buffer != null) { 73 size += buffer.remaining(); 74 } 75 } 76 return size; 77 } 78 79 80 85 public void recycleMemory(ByteBuffer buffer, int minSize) { 86 int remaining = buffer.remaining(); 87 if (remaining >= minSize) { 88 memoryBuffer.add(new SoftReference <ByteBuffer >(buffer.slice())); 89 } 90 } 91 92 public void preallocate(int minSize) { 93 94 } 95 96 97 102 public final synchronized ByteBuffer acquireMemory(int minSize) { 103 ByteBuffer buffer = null; 104 105 if (!memoryBuffer.isEmpty()) { 106 SoftReference <ByteBuffer > freeBuffer = memoryBuffer.remove(0); 107 buffer = freeBuffer.get(); 108 109 if (buffer != null) { 110 if (buffer.limit() < minSize) { 112 buffer = null; 113 } 114 } 115 } 116 117 118 if (buffer == null) { 119 int size = getPreallocationSize(); 120 if (getPreallocationSize() < minSize) { 121 size = minSize * 4; 122 } 123 124 125 buffer = newBuffer(size); 126 } 127 128 return buffer; 129 } 130 131 132 137 public int getPreallocationSize() { 138 return preallocationSize; 139 } 140 141 145 public void setPreallocationSize(int preallocationSize) { 146 this.preallocationSize = preallocationSize; 147 } 148 149 150 151 152 153 154 private final ByteBuffer newBuffer(int size) { 155 if (useDirectMemory) { 156 if (LOG.isLoggable(Level.FINE)) { 157 LOG.fine("allocating " + DataConverter.toFormatedBytesSize(size) + " direct memory"); 158 } 159 160 return ByteBuffer.allocateDirect(size); 161 162 } else { 163 if (LOG.isLoggable(Level.FINE)) { 164 LOG.fine("allocating " + DataConverter.toFormatedBytesSize(size) + " heap memory"); 165 } 166 167 return ByteBuffer.allocate(size); 168 } 169 } 170 171 172 } | Popular Tags |