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
11255c6602
commit
c6bdc2b7dc
|
@ -402,7 +402,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||
buf.trimIndicesToCapacity(newCapacity);
|
||||
bytesToCopy = newCapacity;
|
||||
}
|
||||
memoryCopy(oldMemory, oldOffset, buf.memory, buf.offset, bytesToCopy);
|
||||
memoryCopy(oldMemory, oldOffset, buf, bytesToCopy);
|
||||
if (freeOldMemory) {
|
||||
free(oldChunk, oldNioBuffer, oldHandle, oldMaxLength, buf.cache);
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||
protected abstract PoolChunk<T> newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize);
|
||||
protected abstract PoolChunk<T> newUnpooledChunk(int capacity);
|
||||
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);
|
||||
|
||||
@Override
|
||||
|
@ -686,12 +686,12 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||
}
|
||||
|
||||
@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) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.arraycopy(src, srcOffset, dst, dstOffset, length);
|
||||
System.arraycopy(src, srcOffset, dst.memory, dst.offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -771,7 +771,7 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||
}
|
||||
|
||||
@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) {
|
||||
return;
|
||||
}
|
||||
|
@ -779,13 +779,13 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
|||
if (HAS_UNSAFE) {
|
||||
PlatformDependent.copyMemory(
|
||||
PlatformDependent.directBufferAddress(src) + srcOffset,
|
||||
PlatformDependent.directBufferAddress(dst) + dstOffset, length);
|
||||
PlatformDependent.directBufferAddress(dstBuf.memory) + dstBuf.offset, length);
|
||||
} else {
|
||||
// We must duplicate the NIO buffers because they may be accessed by other Netty buffers.
|
||||
src = src.duplicate();
|
||||
dst = dst.duplicate();
|
||||
ByteBuffer dst = dstBuf.internalNioBuffer();
|
||||
src.position(srcOffset).limit(srcOffset + length);
|
||||
dst.position(dstOffset);
|
||||
dst.position(dstBuf.offset);
|
||||
dst.put(src);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue