Fix memory release failure when "maxNumElems == 1" of PoolSubpage (#10988)
Motivation: when customer need large of 'byteBuf.capacity' in [7168, 8192], the size of 'chunk.subpages' may be inflated when large of byteBuf be released, not consistent with other 'byteBuf.capacity' Modification: when maxNumElems == 1 need consider remove from pool Result: Fixes #10896. Co-authored-by: zxingy <zxingy@servyou.com.cn>
This commit is contained in:
parent
5460ae7d54
commit
d0bcf44445
@ -115,8 +115,14 @@ final class PoolSubpage<T> implements PoolSubpageMetric {
|
||||
|
||||
if (numAvail ++ == 0) {
|
||||
addToPool(head);
|
||||
/* When maxNumElems == 1, the maximum numAvail is also 1.
|
||||
* Each of these PoolSubpages will go in here when they do free operation.
|
||||
* If they return true directly from here, then the rest of the code will be unreachable
|
||||
* and they will not actually be recycled. So return true only on maxNumElems > 1. */
|
||||
if (maxNumElems > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (numAvail != maxNumElems) {
|
||||
return true;
|
||||
|
@ -632,8 +632,8 @@ public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest<Poo
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static PooledByteBuf<ByteBuffer> unwrapIfNeeded(ByteBuf buf) {
|
||||
return (PooledByteBuf<ByteBuffer>) (buf instanceof PooledByteBuf ? buf : buf.unwrap());
|
||||
private static <T> PooledByteBuf<T> unwrapIfNeeded(ByteBuf buf) {
|
||||
return (PooledByteBuf<T>) (buf instanceof PooledByteBuf ? buf : buf.unwrap());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -661,4 +661,27 @@ public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest<Poo
|
||||
assertEquals(3, allocator.metric().directArenas().get(0).numNormalAllocations());
|
||||
buffer.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalPoolSubpageRelease() {
|
||||
// 16 < elemSize <= 7168 or 8192 < elemSize <= 28672, 1 < subpage.maxNumElems <= 256
|
||||
// 7168 <= elemSize <= 8192, subpage.maxNumElems == 1
|
||||
int elemSize = 8192;
|
||||
int length = 1024;
|
||||
ByteBuf[] byteBufs = new ByteBuf[length];
|
||||
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(false, 32, 32, 8192, 11, 256, 64, false, 0);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
byteBufs[i] = allocator.heapBuffer(elemSize, elemSize);
|
||||
}
|
||||
PoolChunk<Object> chunk = unwrapIfNeeded(byteBufs[0]).chunk;
|
||||
|
||||
int beforeFreeBytes = chunk.freeBytes();
|
||||
for (int i = 0; i < length; i++) {
|
||||
byteBufs[i].release();
|
||||
}
|
||||
int afterFreeBytes = chunk.freeBytes();
|
||||
|
||||
assertTrue(beforeFreeBytes < afterFreeBytes);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user