Tagged buffers from MappedByteBufferPool

This commit is contained in:
Greg Wilkins 2015-03-06 11:47:56 +11:00
parent a07ad75a6c
commit 2c3a4869ab
4 changed files with 90 additions and 9 deletions

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.io;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.LeakDetector;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
@ -54,7 +55,7 @@ public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements By
ByteBuffer buffer = delegate.acquire(size,direct);
boolean leakd = leakDetector.acquired(buffer);
if (NOISY || !leakd)
LOG.info(String.format("ByteBuffer acquire %s@%X leakd.acquired=%s",buffer,System.identityHashCode(buffer),leakd ? "normal" : "LEAK"),
LOG.info(String.format("ByteBuffer acquire %s leakd.acquired=%s",BufferUtil.toIDString(buffer),leakd ? "normal" : "LEAK"),
new Throwable("LeakStack.Acquire"));
return buffer;
}
@ -66,7 +67,7 @@ public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements By
return;
boolean leakd = leakDetector.released(buffer);
if (NOISY || !leakd)
LOG.info(String.format("ByteBuffer release %s@%X leakd.released=%s",buffer,System.identityHashCode(buffer),leakd ? "normal" : "LEAK"),
LOG.info(String.format("ByteBuffer release %s leakd.released=%s",BufferUtil.toIDString(buffer),leakd ? "normal" : "LEAK"),
new Throwable("LeakStack.Release"));
delegate.release(buffer);
}

View File

@ -23,6 +23,7 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.util.BufferUtil;
@ -56,13 +57,24 @@ public class MappedByteBufferPool implements ByteBufferPool
if (result == null)
{
int capacity = bucket * factor;
result = direct ? BufferUtil.allocateDirect(capacity) : BufferUtil.allocate(capacity);
result = direct ? createDirect(capacity) : createInDirect(capacity);
}
BufferUtil.clear(result);
return result;
}
protected ByteBuffer createDirect(int capacity)
{
return BufferUtil.allocateDirect(capacity);
}
protected ByteBuffer createInDirect(int capacity)
{
return BufferUtil.allocate(capacity);
}
@Override
public void release(ByteBuffer buffer)
{
@ -108,4 +120,25 @@ public class MappedByteBufferPool implements ByteBufferPool
{
return direct ? directBuffers : heapBuffers;
}
static AtomicInteger __tag = new AtomicInteger();
public static class Tagged extends MappedByteBufferPool
{
protected ByteBuffer createInDirect(int capacity)
{
ByteBuffer buffer = BufferUtil.allocate(capacity+4);
buffer.limit(4);
buffer.putInt(0,__tag.incrementAndGet());
buffer.position(4);
buffer.limit(buffer.capacity());
ByteBuffer slice = buffer.slice();
BufferUtil.clear(slice);
return slice;
}
protected ByteBuffer createDirect(int capacity)
{
return createInDirect(capacity);
}
}
}

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.io;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
@ -29,7 +30,9 @@ import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.hamcrest.Matchers;
import org.junit.Test;
public class MappedByteBufferPoolTest
@ -113,4 +116,16 @@ public class MappedByteBufferPoolTest
// Expected path.
}
}
@Test
public void testTagged()
{
MappedByteBufferPool pool = new MappedByteBufferPool.Tagged();
ByteBuffer buffer = pool.acquire(1024,false);
assertThat(BufferUtil.toDetailString(buffer),containsString("@T00000001"));
buffer = pool.acquire(1024,false);
assertThat(BufferUtil.toDetailString(buffer),containsString("@T00000002"));
}
}

View File

@ -920,6 +920,43 @@ public class BufferUtil
return builder.toString();
}
/* ------------------------------------------------------------ */
/** Convert Buffer to string ID independent of content
* @param buffer
* @return A string showing the buffer ID
*/
public static void idString(ByteBuffer buffer, StringBuilder out)
{
out.append(buffer.getClass().getSimpleName());
out.append("@");
if (buffer.hasArray() && buffer.arrayOffset()==4)
{
out.append('T');
byte[] array = buffer.array();
TypeUtil.toHex(array[0],out);
TypeUtil.toHex(array[1],out);
TypeUtil.toHex(array[2],out);
TypeUtil.toHex(array[3],out);
}
else
out.append(Integer.toHexString(System.identityHashCode(buffer)));
}
/* ------------------------------------------------------------ */
/** Convert Buffer to string ID independent of content
* @param buffer
* @return A string showing the buffer ID
*/
public static String toIDString(ByteBuffer buffer)
{
StringBuilder buf = new StringBuilder();
idString(buffer,buf);
return buf.toString();
}
/* ------------------------------------------------------------ */
/** Convert Buffer to a detail debug string of pointers and content
* @param buffer
@ -931,12 +968,7 @@ public class BufferUtil
return "null";
StringBuilder buf = new StringBuilder();
buf.append(buffer.getClass().getSimpleName());
buf.append("@");
if (buffer.hasArray())
buf.append(Integer.toHexString(Arrays.hashCode(buffer.array())));
else
buf.append(Integer.toHexString(buf.hashCode()));
idString(buffer,buf);
buf.append("[p=");
buf.append(buffer.position());
buf.append(",l=");