Reduce ByteBuffer duplication when resizing pooled direct ByteBufs (#9765)
Motivation: Currently when use of Unsafe is disabled and an internal reallocation is performed for a direct PooledByteBuf, a one-off temporary duplicate is made of the source and destination backing nio buffers so that the copy can be done in a threadsafe manner. The need for this can be reduced by sharing the temporary duplicate buffer that is already stored in the corresponding destination PooledByteBuf instance. Modifications: Have PoolArena#memoryCopy(...) take the destination PooledByteBuf instead of the underlying mem reference and offset, and use internalNioBuffer() to obtain/initialize a reusable duplicate of the backing nio buffer. Result: Fewer temporary allocations when resizing direct pooled ByteBufs in the non-Unsafe case
This commit is contained in:
parent
e55e3a59f9
commit
b0feb5a81f
@ -402,7 +402,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
buf.trimIndicesToCapacity(newCapacity);
|
buf.trimIndicesToCapacity(newCapacity);
|
||||||
bytesToCopy = newCapacity;
|
bytesToCopy = newCapacity;
|
||||||
}
|
}
|
||||||
memoryCopy(oldMemory, oldOffset, buf.memory, buf.offset, bytesToCopy);
|
memoryCopy(oldMemory, oldOffset, buf, bytesToCopy);
|
||||||
if (freeOldMemory) {
|
if (freeOldMemory) {
|
||||||
free(oldChunk, oldNioBuffer, oldHandle, oldMaxLength, buf.cache);
|
free(oldChunk, oldNioBuffer, oldHandle, oldMaxLength, buf.cache);
|
||||||
}
|
}
|
||||||
@ -569,7 +569,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
protected abstract PoolChunk<T> newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize);
|
protected abstract PoolChunk<T> newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize);
|
||||||
protected abstract PoolChunk<T> newUnpooledChunk(int capacity);
|
protected abstract PoolChunk<T> newUnpooledChunk(int capacity);
|
||||||
protected abstract PooledByteBuf<T> newByteBuf(int maxCapacity);
|
protected abstract PooledByteBuf<T> newByteBuf(int maxCapacity);
|
||||||
protected abstract void memoryCopy(T src, int srcOffset, T dst, int dstOffset, int length);
|
protected abstract void memoryCopy(T src, int srcOffset, PooledByteBuf<T> dst, int length);
|
||||||
protected abstract void destroyChunk(PoolChunk<T> chunk);
|
protected abstract void destroyChunk(PoolChunk<T> chunk);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -692,12 +692,12 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void memoryCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int length) {
|
protected void memoryCopy(byte[] src, int srcOffset, PooledByteBuf<byte[]> dst, int length) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.arraycopy(src, srcOffset, dst, dstOffset, length);
|
System.arraycopy(src, srcOffset, dst.memory, dst.offset, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,7 +777,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void memoryCopy(ByteBuffer src, int srcOffset, ByteBuffer dst, int dstOffset, int length) {
|
protected void memoryCopy(ByteBuffer src, int srcOffset, PooledByteBuf<ByteBuffer> dstBuf, int length) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -785,13 +785,13 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||||||
if (HAS_UNSAFE) {
|
if (HAS_UNSAFE) {
|
||||||
PlatformDependent.copyMemory(
|
PlatformDependent.copyMemory(
|
||||||
PlatformDependent.directBufferAddress(src) + srcOffset,
|
PlatformDependent.directBufferAddress(src) + srcOffset,
|
||||||
PlatformDependent.directBufferAddress(dst) + dstOffset, length);
|
PlatformDependent.directBufferAddress(dstBuf.memory) + dstBuf.offset, length);
|
||||||
} else {
|
} else {
|
||||||
// We must duplicate the NIO buffers because they may be accessed by other Netty buffers.
|
// We must duplicate the NIO buffers because they may be accessed by other Netty buffers.
|
||||||
src = src.duplicate();
|
src = src.duplicate();
|
||||||
dst = dst.duplicate();
|
ByteBuffer dst = dstBuf.internalNioBuffer();
|
||||||
src.position(srcOffset).limit(srcOffset + length);
|
src.position(srcOffset).limit(srcOffset + length);
|
||||||
dst.position(dstOffset);
|
dst.position(dstBuf.offset);
|
||||||
dst.put(src);
|
dst.put(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user