Add PooledSlicedByteBuf and PooledDuplicatedByteBuf
Motivation: At the moment when calling slice(...) or duplicate(...) on a Pooled*ByteBuf a new SlicedByteBuf or DuplicatedByteBuf. This can create a lot of GC. Modifications: Add PooledSlicedByteBuf and PooledDuplicatedByteBuf which will be used when a PooledByteBuf is used. Result: Less GC.
This commit is contained in:
parent
a73a3ce7a6
commit
627831d658
@ -59,12 +59,20 @@ public abstract class AbstractDerivedByteBuf extends AbstractByteBuf {
|
||||
|
||||
@Override
|
||||
public final boolean release() {
|
||||
return unwrap().release();
|
||||
if (unwrap().release()) {
|
||||
deallocate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean release(int decrement) {
|
||||
return unwrap().release(decrement);
|
||||
if (unwrap().release(decrement)) {
|
||||
deallocate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,4 +84,9 @@ public abstract class AbstractDerivedByteBuf extends AbstractByteBuf {
|
||||
public ByteBuffer nioBuffer(int index, int length) {
|
||||
return unwrap().nioBuffer(index, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the wrapped {@link ByteBuf} was released due calling of {@link #release()} or {@link #release(int)}.
|
||||
*/
|
||||
protected void deallocate() { }
|
||||
}
|
||||
|
@ -33,11 +33,19 @@ import java.nio.channels.ScatteringByteChannel;
|
||||
*/
|
||||
public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
||||
|
||||
private final ByteBuf buffer;
|
||||
private ByteBuf buffer;
|
||||
|
||||
public DuplicatedByteBuf(ByteBuf buffer) {
|
||||
super(buffer.maxCapacity());
|
||||
init(buffer);
|
||||
}
|
||||
|
||||
DuplicatedByteBuf(int maxCapacity) {
|
||||
super(maxCapacity);
|
||||
}
|
||||
|
||||
final void init(ByteBuf buffer) {
|
||||
maxCapacity(buffer.maxCapacity());
|
||||
if (buffer instanceof DuplicatedByteBuf) {
|
||||
this.buffer = ((DuplicatedByteBuf) buffer).buffer;
|
||||
} else {
|
||||
@ -45,6 +53,8 @@ public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
||||
}
|
||||
|
||||
setIndex(buffer.readerIndex(), buffer.writerIndex());
|
||||
markReaderIndex();
|
||||
markWriterIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,6 +70,16 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
||||
initThread = Thread.currentThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf slice(int index, int length) {
|
||||
return PooledSlicedByteBuf.newInstance(this, index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf duplicate() {
|
||||
return PooledDuplicatedByteBuf.newInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int capacity() {
|
||||
return length;
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.Recycler;
|
||||
|
||||
final class PooledDuplicatedByteBuf extends DuplicatedByteBuf {
|
||||
|
||||
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
|
||||
@Override
|
||||
protected PooledDuplicatedByteBuf newObject(Handle handle) {
|
||||
return new PooledDuplicatedByteBuf(handle);
|
||||
}
|
||||
};
|
||||
|
||||
static PooledDuplicatedByteBuf newInstance(ByteBuf buffer) {
|
||||
PooledDuplicatedByteBuf buf = RECYCLER.get();
|
||||
buf.init(buffer);
|
||||
return buf;
|
||||
}
|
||||
|
||||
private final Recycler.Handle recyclerHandle;
|
||||
|
||||
private PooledDuplicatedByteBuf(Recycler.Handle recyclerHandle) {
|
||||
super(0);
|
||||
this.recyclerHandle = recyclerHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf slice(int index, int length) {
|
||||
return PooledSlicedByteBuf.newInstance(this, index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf duplicate() {
|
||||
return newInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deallocate() {
|
||||
RECYCLER.recycle(this, recyclerHandle);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.Recycler;
|
||||
|
||||
final class PooledSlicedByteBuf extends SlicedByteBuf {
|
||||
|
||||
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
|
||||
@Override
|
||||
protected PooledSlicedByteBuf newObject(Handle handle) {
|
||||
return new PooledSlicedByteBuf(handle);
|
||||
}
|
||||
};
|
||||
|
||||
static PooledSlicedByteBuf newInstance(ByteBuf buffer, int index, int length) {
|
||||
PooledSlicedByteBuf buf = RECYCLER.get();
|
||||
buf.init(buffer, index, length);
|
||||
return buf;
|
||||
}
|
||||
|
||||
private final Recycler.Handle recyclerHandle;
|
||||
|
||||
private PooledSlicedByteBuf(Recycler.Handle recyclerHandle) {
|
||||
super(0);
|
||||
this.recyclerHandle = recyclerHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf slice(int index, int length) {
|
||||
return newInstance(this, index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf duplicate() {
|
||||
return PooledDuplicatedByteBuf.newInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deallocate() {
|
||||
RECYCLER.recycle(this, recyclerHandle);
|
||||
}
|
||||
}
|
@ -34,12 +34,20 @@ import java.nio.channels.ScatteringByteChannel;
|
||||
*/
|
||||
public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
||||
|
||||
private final ByteBuf buffer;
|
||||
private final int adjustment;
|
||||
private final int length;
|
||||
private ByteBuf buffer;
|
||||
private int adjustment;
|
||||
private int length;
|
||||
|
||||
public SlicedByteBuf(ByteBuf buffer, int index, int length) {
|
||||
super(length);
|
||||
init(buffer, index, length);
|
||||
}
|
||||
|
||||
SlicedByteBuf(int length) {
|
||||
super(length);
|
||||
}
|
||||
|
||||
final void init(ByteBuf buffer, int index, int length) {
|
||||
if (index < 0 || index > buffer.capacity() - length) {
|
||||
throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
|
||||
}
|
||||
@ -55,8 +63,9 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
||||
adjustment = index;
|
||||
}
|
||||
this.length = length;
|
||||
|
||||
writerIndex(length);
|
||||
maxCapacity(length);
|
||||
setIndex(0, length);
|
||||
discardMarks();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user