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

reuse allocated buffer #271

Merged
merged 4 commits into from
Jul 6, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ func NewEncoder() *Encoder {

// Clean clean the Encoder (room) for a new object encoding.
func (e *Encoder) Clean() {
buffer := make([]byte, 64)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wongoo Making a slice of byte have an advantage: avoiding memory leak caused by growth of underlying array . but making it , when call method Clean every time, is unnecessary too. the underlying array can be reused.
this PR, have two advantages:

  • reusing the buffer (reducing memory-allocation);
  • avoiding memory leak caused by growth of underlying array

var buffer []byte
if len(e.buffer) <= 128 {
Copy link
Contributor

Choose a reason for hiding this comment

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

does it need to check the buffer length?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i am sorry, i made a typo. cap , not len.

if not check the buffer capacity. there is a risk of memory leak. for example, an encoder encodes an huge object (eg: 100K ), the allocated room of buffer is also so big. generally, most of object is not such huge. it causes most of buffer room is not used and not GC . it is

128 may be too small for most situation,i suggest to change it to 512,or allow user to chang it by ‘hessian.SetReuseBufferSize(int)’

good idea

// reuse buffer, avoid allocate
buffer = e.buffer[:0]
} else {
buffer = make([]byte, 64)
}
e.classInfoList = nil
e.buffer = buffer[:0]
e.refMap = make(map[unsafe.Pointer]_refElem, 7)
Expand Down