From 73b0386ad46bbc4919b293eb26c4a48d8809e5b4 Mon Sep 17 00:00:00 2001 From: allwmh Date: Thu, 6 Mar 2014 23:09:30 -0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96CircularQueue=E7=9A=84=E9=95=BF=E5=BA=A6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/buffer/CachedBufferAllocator.java | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java b/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java index 01ac3f6..62ec796 100644 --- a/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java +++ b/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java @@ -34,24 +34,24 @@ */ package com.taobao.gecko.core.buffer; +import com.taobao.gecko.core.util.CircularQueue; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.HashMap; import java.util.Map; import java.util.Queue; -import com.taobao.gecko.core.util.CircularQueue; - /** * An {@link IoBufferAllocator} that caches the buffers which are likely to be * reused during auto-expansion of the buffers. - *

+ *

* In {@link SimpleBufferAllocator}, the underlying {@link ByteBuffer} of the * {@link IoBuffer} is reallocated on its capacity change, which means the newly * allocated bigger {@link ByteBuffer} replaces the old small {@link ByteBuffer} * . Consequently, the old {@link ByteBuffer} is marked for garbage collection. - *

+ *

* It's not a problem in most cases as long as the capacity change doesn't * happen frequently. However, once it happens too often, it burdens the VM and * the cost of filling the newly allocated {@link ByteBuffer} with {@code NUL} @@ -66,11 +66,11 @@ * * Please note the observation above is subject to change in a different * environment. - *

+ *

* {@link CachedBufferAllocator} uses {@link ThreadLocal} to store the cached * buffer, allocates buffers whose capacity is power of 2 only and provides * performance advantage if {@link IoBuffer#free()} is called properly. - * + * * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 671827 $, $Date: 2008-06-26 10:49:48 +0200 (Thu, 26 Jun 2008) * $ @@ -99,14 +99,12 @@ public CachedBufferAllocator() { /** * Creates a new instance. - * - * @param maxPoolSize - * the maximum number of buffers with the same capacity per - * thread. 0 disables this limitation. - * @param maxCachedBufferSize - * the maximum capacity of a cached buffer. A buffer whose - * capacity is bigger than this value is not pooled. 0 - * disables this limitation. + * + * @param maxPoolSize the maximum number of buffers with the same capacity per + * thread. 0 disables this limitation. + * @param maxCachedBufferSize the maximum capacity of a cached buffer. A buffer whose + * capacity is bigger than this value is not pooled. 0 + * disables this limitation. */ public CachedBufferAllocator(final int maxPoolSize, final int maxCachedBufferSize) { if (maxPoolSize < 0) { @@ -156,7 +154,11 @@ public int getMaxCachedBufferSize() { private Map> newPoolMap() { final Map> poolMap = new HashMap>(); final int poolSize = this.maxPoolSize == 0 ? DEFAULT_MAX_POOL_SIZE : this.maxPoolSize; - for (int i = 0; i < 31; i++) { + int cachedQueueNum = IoBuffer.normalizeCapacity(this.getMaxCachedBufferSize()); + if (this.getMaxCachedBufferSize() % 2 == 1) { + cachedQueueNum--; + } + for (int i = 0; i < cachedQueueNum; i++) { poolMap.put(1 << i, new CircularQueue(poolSize)); } poolMap.put(0, new CircularQueue(poolSize)); @@ -171,17 +173,14 @@ public IoBuffer allocate(final int requestedCapacity, final boolean direct) { if (this.maxCachedBufferSize != 0 && actualCapacity > this.maxCachedBufferSize) { if (direct) { buf = this.wrap(ByteBuffer.allocateDirect(actualCapacity)); - } - else { + } else { buf = this.wrap(ByteBuffer.allocate(actualCapacity)); } - } - else { + } else { Queue pool; if (direct) { pool = this.directBuffers.get().get(actualCapacity); - } - else { + } else { pool = this.heapBuffers.get().get(actualCapacity); } @@ -191,12 +190,10 @@ public IoBuffer allocate(final int requestedCapacity, final boolean direct) { buf.clear(); buf.setAutoExpand(false); buf.order(ByteOrder.BIG_ENDIAN); - } - else { + } else { if (direct) { buf = this.wrap(ByteBuffer.allocateDirect(actualCapacity)); - } - else { + } else { buf = this.wrap(ByteBuffer.allocate(actualCapacity)); } } @@ -310,8 +307,7 @@ private void free(final ByteBuffer oldBuf) { Queue pool; if (oldBuf.isDirect()) { pool = CachedBufferAllocator.this.directBuffers.get().get(oldBuf.capacity()); - } - else { + } else { pool = CachedBufferAllocator.this.heapBuffers.get().get(oldBuf.capacity()); } From d327dcd26015f42c8388943def62c6a0cfcca1ce Mon Sep 17 00:00:00 2001 From: allwmh Date: Thu, 13 Mar 2014 06:28:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BAGBK=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/buffer/CachedBufferAllocator.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java b/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java index 62ec796..3181963 100644 --- a/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java +++ b/src/main/java/com/taobao/gecko/core/buffer/CachedBufferAllocator.java @@ -80,7 +80,7 @@ public class CachedBufferAllocator implements IoBufferAllocator { private static final int DEFAULT_MAX_POOL_SIZE = 8; private static final int DEFAULT_MAX_CACHED_BUFFER_SIZE = 1 << 18; // 256KB - private final int maxPoolSize; + private final int maxPoolSize;//等于0表示不限制CircularQueue的长度 private final int maxCachedBufferSize; private final ThreadLocal>> heapBuffers; @@ -151,22 +151,17 @@ public int getMaxCachedBufferSize() { } - private Map> newPoolMap() { + public Map> newPoolMap() { final Map> poolMap = new HashMap>(); final int poolSize = this.maxPoolSize == 0 ? DEFAULT_MAX_POOL_SIZE : this.maxPoolSize; - int cachedQueueNum = IoBuffer.normalizeCapacity(this.getMaxCachedBufferSize()); - if (this.getMaxCachedBufferSize() % 2 == 1) { - cachedQueueNum--; - } - for (int i = 0; i < cachedQueueNum; i++) { - poolMap.put(1 << i, new CircularQueue(poolSize)); - } + int maxCachedBufferSize = IoBuffer.normalizeCapacity(this.getMaxCachedBufferSize()); poolMap.put(0, new CircularQueue(poolSize)); - poolMap.put(Integer.MAX_VALUE, new CircularQueue(poolSize)); + for (int cachedBufferSize = maxCachedBufferSize; cachedBufferSize > 0; cachedBufferSize = cachedBufferSize >> 1) { + poolMap.put(cachedBufferSize, new CircularQueue(poolSize)); + } return poolMap; } - public IoBuffer allocate(final int requestedCapacity, final boolean direct) { final int actualCapacity = IoBuffer.normalizeCapacity(requestedCapacity); IoBuffer buf;