Enable PooledByteBufAllocator to work, event without a cache
Motivation: `useCacheForAllThreads` may be false which disables memory caching on non netty threads. Setting this argument or the system property makes it impossible to use `PooledByteBufAllocator`. Modifications: Delayed the check of `freeSweepAllocationThreshold` in `PoolThreadCache` to after it knows there will be any caches in use. Additionally, check if the caches will have any data in them (rather than allocating a 0-length array). A test case is also added that fails without this change. Results: Fixes #7194
This commit is contained in:
parent
c0396818ca
commit
d2cb51bc2e
@ -71,10 +71,6 @@ final class PoolThreadCache {
|
|||||||
throw new IllegalArgumentException("maxCachedBufferCapacity: "
|
throw new IllegalArgumentException("maxCachedBufferCapacity: "
|
||||||
+ maxCachedBufferCapacity + " (expected: >= 0)");
|
+ maxCachedBufferCapacity + " (expected: >= 0)");
|
||||||
}
|
}
|
||||||
if (freeSweepAllocationThreshold < 1) {
|
|
||||||
throw new IllegalArgumentException("freeSweepAllocationThreshold: "
|
|
||||||
+ freeSweepAllocationThreshold + " (expected: > 0)");
|
|
||||||
}
|
|
||||||
this.freeSweepAllocationThreshold = freeSweepAllocationThreshold;
|
this.freeSweepAllocationThreshold = freeSweepAllocationThreshold;
|
||||||
this.heapArena = heapArena;
|
this.heapArena = heapArena;
|
||||||
this.directArena = directArena;
|
this.directArena = directArena;
|
||||||
@ -119,6 +115,11 @@ final class PoolThreadCache {
|
|||||||
// We only need to watch the thread when any cache is used.
|
// We only need to watch the thread when any cache is used.
|
||||||
if (tinySubPageDirectCaches != null || smallSubPageDirectCaches != null || normalDirectCaches != null
|
if (tinySubPageDirectCaches != null || smallSubPageDirectCaches != null || normalDirectCaches != null
|
||||||
|| tinySubPageHeapCaches != null || smallSubPageHeapCaches != null || normalHeapCaches != null) {
|
|| tinySubPageHeapCaches != null || smallSubPageHeapCaches != null || normalHeapCaches != null) {
|
||||||
|
// Only check freeSweepAllocationThreshold when there are caches in use.
|
||||||
|
if (freeSweepAllocationThreshold < 1) {
|
||||||
|
throw new IllegalArgumentException("freeSweepAllocationThreshold: "
|
||||||
|
+ freeSweepAllocationThreshold + " (expected: > 0)");
|
||||||
|
}
|
||||||
freeTask = new Runnable() {
|
freeTask = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -139,7 +140,7 @@ final class PoolThreadCache {
|
|||||||
|
|
||||||
private static <T> MemoryRegionCache<T>[] createSubPageCaches(
|
private static <T> MemoryRegionCache<T>[] createSubPageCaches(
|
||||||
int cacheSize, int numCaches, SizeClass sizeClass) {
|
int cacheSize, int numCaches, SizeClass sizeClass) {
|
||||||
if (cacheSize > 0) {
|
if (cacheSize > 0 && numCaches > 0) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
MemoryRegionCache<T>[] cache = new MemoryRegionCache[numCaches];
|
MemoryRegionCache<T>[] cache = new MemoryRegionCache[numCaches];
|
||||||
for (int i = 0; i < cache.length; i++) {
|
for (int i = 0; i < cache.length; i++) {
|
||||||
@ -154,7 +155,7 @@ final class PoolThreadCache {
|
|||||||
|
|
||||||
private static <T> MemoryRegionCache<T>[] createNormalCaches(
|
private static <T> MemoryRegionCache<T>[] createNormalCaches(
|
||||||
int cacheSize, int maxCachedBufferCapacity, PoolArena<T> area) {
|
int cacheSize, int maxCachedBufferCapacity, PoolArena<T> area) {
|
||||||
if (cacheSize > 0) {
|
if (cacheSize > 0 && maxCachedBufferCapacity > 0) {
|
||||||
int max = Math.min(area.chunkSize, maxCachedBufferCapacity);
|
int max = Math.min(area.chunkSize, maxCachedBufferCapacity);
|
||||||
int arraySize = Math.max(1, log2(max / area.pageSize) + 1);
|
int arraySize = Math.max(1, log2(max / area.pageSize) + 1);
|
||||||
|
|
||||||
|
@ -77,6 +77,24 @@ public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest<Poo
|
|||||||
heapBuffer.release();
|
heapBuffer.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithoutUseCacheForAllThreads() {
|
||||||
|
assertFalse(Thread.currentThread() instanceof FastThreadLocalThread);
|
||||||
|
|
||||||
|
PooledByteBufAllocator pool = new PooledByteBufAllocator(
|
||||||
|
/*preferDirect=*/ false,
|
||||||
|
/*nHeapArena=*/ 1,
|
||||||
|
/*nDirectArena=*/ 1,
|
||||||
|
/*pageSize=*/8192,
|
||||||
|
/*maxOrder=*/ 11,
|
||||||
|
/*tinyCacheSize=*/ 0,
|
||||||
|
/*smallCacheSize=*/ 0,
|
||||||
|
/*normalCacheSize=*/ 0,
|
||||||
|
/*useCacheForAllThreads=*/ false);
|
||||||
|
ByteBuf buf = pool.buffer(1);
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArenaMetricsNoCache() {
|
public void testArenaMetricsNoCache() {
|
||||||
testArenaMetrics0(new PooledByteBufAllocator(true, 2, 2, 8192, 11, 0, 0, 0), 100, 0, 100, 100);
|
testArenaMetrics0(new PooledByteBufAllocator(true, 2, 2, 8192, 11, 0, 0, 0), 100, 0, 100, 100);
|
||||||
|
Loading…
Reference in New Issue
Block a user