Skip to content

Commit f10f8a3

Browse files
isdomnormanmaurer
authored andcommittedJan 30, 2017
Calculate correct count for tiny/small/normal allocation
Motivation: Disable ThreadLocal Cache, then allocate Pooled ByteBuf and release all these buffers, PoolArena's tiny/small/normal allocation count is incorrect. Modifications: - Calculate PoolArena's tiny/small/normal allocation one time - Add testAllocationCounter TestCase Result: Fixes #6282 .
1 parent 94cb389 commit f10f8a3

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed
 

‎buffer/src/main/java/io/netty/buffer/PoolArena.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,47 +201,56 @@ private void allocate(PoolThreadCache cache, PooledByteBuf<T> buf, final int req
201201
long handle = s.allocate();
202202
assert handle >= 0;
203203
s.chunk.initBufWithSubpage(buf, handle, reqCapacity);
204-
205-
if (tiny) {
206-
allocationsTiny.increment();
207-
} else {
208-
allocationsSmall.increment();
209-
}
204+
incTinySmallAllocation(tiny);
210205
return;
211206
}
212207
}
213-
allocateNormal(buf, reqCapacity, normCapacity);
208+
synchronized (this) {
209+
allocateNormal(buf, reqCapacity, normCapacity);
210+
}
211+
212+
incTinySmallAllocation(tiny);
214213
return;
215214
}
216215
if (normCapacity <= chunkSize) {
217216
if (cache.allocateNormal(this, buf, reqCapacity, normCapacity)) {
218217
// was able to allocate out of the cache so move on
219218
return;
220219
}
221-
allocateNormal(buf, reqCapacity, normCapacity);
220+
synchronized (this) {
221+
allocateNormal(buf, reqCapacity, normCapacity);
222+
++allocationsNormal;
223+
}
222224
} else {
223225
// Huge allocations are never served via the cache so just call allocateHuge
224226
allocateHuge(buf, reqCapacity);
225227
}
226228
}
227229

228-
private synchronized void allocateNormal(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) {
230+
// Method must be called insided synchronized(this) { ... } block
231+
private void allocateNormal(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) {
229232
if (q050.allocate(buf, reqCapacity, normCapacity) || q025.allocate(buf, reqCapacity, normCapacity) ||
230233
q000.allocate(buf, reqCapacity, normCapacity) || qInit.allocate(buf, reqCapacity, normCapacity) ||
231234
q075.allocate(buf, reqCapacity, normCapacity)) {
232-
++allocationsNormal;
233235
return;
234236
}
235237

236238
// Add a new chunk.
237239
PoolChunk<T> c = newChunk(pageSize, maxOrder, pageShifts, chunkSize);
238240
long handle = c.allocate(normCapacity);
239-
++allocationsNormal;
240241
assert handle > 0;
241242
c.initBuf(buf, handle, reqCapacity);
242243
qInit.add(c);
243244
}
244245

246+
private void incTinySmallAllocation(boolean tiny) {
247+
if (tiny) {
248+
allocationsTiny.increment();
249+
} else {
250+
allocationsSmall.increment();
251+
}
252+
}
253+
245254
private void allocateHuge(PooledByteBuf<T> buf, int reqCapacity) {
246255
PoolChunk<T> chunk = newUnpooledChunk(reqCapacity);
247256
activeBytesHuge.add(chunk.chunkSize());

‎buffer/src/test/java/io/netty/buffer/PoolArenaTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,49 @@ public void testNormalizeCapacity() throws Exception {
3232
Assert.assertEquals(expectedResult[i], arena.normalizeCapacity(reqCapacities[i]));
3333
}
3434
}
35+
36+
@Test
37+
public final void testAllocationCounter() {
38+
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(
39+
true, // preferDirect
40+
0, // nHeapArena
41+
1, // nDirectArena
42+
8192, // pageSize
43+
11, // maxOrder
44+
0, // tinyCacheSize
45+
0, // smallCacheSize
46+
0, // normalCacheSize
47+
true // useCacheForAllThreads
48+
);
49+
50+
// create tiny buffer
51+
final ByteBuf b1 = allocator.directBuffer(24);
52+
// create small buffer
53+
final ByteBuf b2 = allocator.directBuffer(800);
54+
// create normal buffer
55+
final ByteBuf b3 = allocator.directBuffer(8192 * 2);
56+
57+
Assert.assertNotNull(b1);
58+
Assert.assertNotNull(b2);
59+
Assert.assertNotNull(b3);
60+
61+
// then release buffer to deallocated memory while threadlocal cache has been disabled
62+
// allocations counter value must equals deallocations counter value
63+
Assert.assertTrue(b1.release());
64+
Assert.assertTrue(b2.release());
65+
Assert.assertTrue(b3.release());
66+
67+
Assert.assertTrue(allocator.directArenas().size() >= 1);
68+
final PoolArenaMetric metric = allocator.directArenas().get(0);
69+
70+
Assert.assertEquals(3, metric.numDeallocations());
71+
Assert.assertEquals(3, metric.numAllocations());
72+
73+
Assert.assertEquals(1, metric.numTinyDeallocations());
74+
Assert.assertEquals(1, metric.numTinyAllocations());
75+
Assert.assertEquals(1, metric.numSmallDeallocations());
76+
Assert.assertEquals(1, metric.numSmallAllocations());
77+
Assert.assertEquals(1, metric.numNormalDeallocations());
78+
Assert.assertEquals(1, metric.numNormalAllocations());
79+
}
3580
}

0 commit comments

Comments
 (0)
Please sign in to comment.