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);
|
||||
bytesToCopy = newCapacity;
|
||||
}
|
||||
memoryCopy(oldMemory, oldOffset, buf.memory, buf.offset, bytesToCopy);
|
||||
memoryCopy(oldMemory, oldOffset, buf, bytesToCopy);
|
||||
if (freeOldMemory) {
|
||||
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> 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
|
||||
@ -692,12 +692,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -777,7 +777,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;
|
||||
}
|
||||
@ -785,13 +785,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
Block a user