Skip to content
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

Closed
wants to merge 2 commits into from

Conversation

trustin
Copy link
Member

@trustin trustin commented Apr 13, 2016

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

@trustin trustin added this to the 4.1.0.Final milestone Apr 13, 2016
@trustin
Copy link
Member Author

trustin commented Apr 13, 2016

@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 Retained before cherry-picking.

@@ -1,5 +1,5 @@
/*
* Copyright 2012 The Netty Project
* Copyright 2016 The Netty Project
Copy link
Member

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
Copy link
Member

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
@normanmaurer
Copy link
Member

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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR Remove this unnecessary cast to "Handle". rule

@trustin
Copy link
Member Author

trustin commented Apr 13, 2016

Will open a clean PR after rebasing.

@trustin trustin closed this Apr 13, 2016
@trustin trustin removed this from the 4.1.0.Final milestone Apr 13, 2016
@Scottmitch
Copy link
Member

@trustin - don't forget to delete this branch when its no longer needed.

trustin added a commit that referenced this pull request Apr 14, 2016
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()
trustin added a commit that referenced this pull request Apr 14, 2016
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()
trustin added a commit that referenced this pull request Apr 16, 2016
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()
trustin added a commit that referenced this pull request Apr 17, 2016
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()
trustin added a commit that referenced this pull request May 6, 2016
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
trustin added a commit that referenced this pull request May 7, 2016
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
trustin added a commit that referenced this pull request May 14, 2016
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
normanmaurer pushed a commit that referenced this pull request May 17, 2016
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
@normanmaurer
Copy link
Member

Fixed by #5144

@normanmaurer normanmaurer deleted the recycle_derived_buf branch May 17, 2016 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants