New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make derived buffers recyclable / Add missing overrides to ByteBuf impls #5128
Conversation
@ninja-, @merlimat, @normanmaurer PTAL. Please let me know if there's any regression. It changes how reference counting works for derived buffers. I think we can remove the methods that ends with |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 2012 The Netty Project | |||
* Copyright 2016 The Netty Project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I think we never change the year on existing files. So revert ?
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 2012 The Netty Project | |||
* Copyright 2016 The Netty Project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert
Related: #4333 #4421 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Deprecate the old derived buffer implementations - Add the new recyclable derived buffer implementations, which has its own reference count value - When a derived buffer is created, its internal reference count is 0. - When retain() is called on a derived buffer, the internal reference count becomes a positive value and the original buffer's retain() is called. - When release() is called on a derived buffer, the internal reference count is decreased first, and then the original buffer's release() is called when the internal reference count is 0. - Add ByteBufUtil.duplicate/slice() so that a user can easily implement ByteBuf.duplicate/slice() - Add missing overrides in some ByteBuf impls - Fix incorrect range checks in SlicedByteBuf - Miscellaneous: - Merge Duplicated/SlicedAbstractByteBuf.unwrap0() into unwrap() using covariant return type Result: - Derived buffers are now recycled when retained and released, although they are not recycled if a user called release() against the original buffer. buf.slice().retain().release(); // recycled buf.slice().retain(); buf.release(); // not recycled - Correct range checks in SlicedByteBuf
46e3ce7
to
35c493d
Compare
Talked to @trustin, please hold back with review this needs some changes. |
@SuppressWarnings("unchecked") | ||
AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf<T>> recyclerHandle) { | ||
super(0); | ||
this.recyclerHandle = (Handle<AbstractPooledDerivedByteBuf<T>>) recyclerHandle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will open a clean PR after rebasing. |
@trustin - don't forget to delete this branch when its no longer needed. |
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufUtil.duplicateRetained/sliceRetained() so that a user can easily implement ByteBuf.duplicateRetained/sliceRetained() - Use duplicateRetained() and sliceRetained() wherever possible Result: Derived buffers are now recycled when created via sliceRetained() and duplicateRetained()
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add ByteBuf.rslice/rduplicate/readRSlice() which creates a non-recyclable derived buffer - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufUtil.rduplicate/rslice() so that a user can easily implement ByteBuf.rduplicate/rslice() - Add ByteBufHolder.rduplicate() - Add a new protected method DefaultByteBufHolder.copy(ByteBuf) so that a user can implement copy/duplicate/rduplicate() easily - Use rduplicate() and rslice() wherever possible Result: Derived buffers are now recycled when created via rslice() and rduplicate()
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufUtil.retainedSlice() and retainedDuplicate() so that a user can implement the new ByteBuf methods easily - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate()
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufUtil.retainedSlice() and retainedDuplicate() so that a user can implement the new ByteBuf methods easily - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate()
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufUtil.retainedSlice() and retainedDuplicate() so that a user can implement the new ByteBuf methods easily - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate() and derived from a pooled buffer
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate() and derived from a pooled buffer
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') - Make ReplayingDecoderByteBuf.reject() return an exception instead of throwing it so that its callers don't need to add dummy return statement Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate() and derived from a pooled buffer
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') - Make ReplayingDecoderByteBuf.reject() return an exception instead of throwing it so that its callers don't need to add dummy return statement Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate() and derived from a pooled buffer
Fixed by #5144 |
Related: #4333 #4421
Motivation:
slice(), duplicate() and readSlice() currently create a non-recyclable
derived buffer instance. Under heavy load, an application that creates a
lot of derived buffers can put the garbage collector under pressure.
Modifications:
own reference count value
count becomes a positive value and the original buffer's retain() is
called.
count is decreased first, and then the original buffer's release()
is called when the internal reference count is 0.
ByteBuf.duplicate/slice()
covariant return type
Result:
Derived buffers are now recycled when retained and released, although
they are not recycled if a user called release() against the original
buffer.
buf.slice().retain().release(); // recycled
buf.slice().retain(); buf.release(); // not recycled
Correct range checks in SlicedByteBuf