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

Fix memory leak in freeNode and splitNode. #11

Merged
merged 2 commits into from
Oct 5, 2016
Merged

Conversation

keep94
Copy link
Contributor

@keep94 keep94 commented Oct 5, 2016

This PR includes two important changes to help the GC reclaim memory. Both changes involve making sure that elements past the end of a slice but still within the slice's capacity can be gced.

The first change is freelist.newNode() setting the last element to nil in the freelist before shrinking the size of the freelist by 1.

The second change is adding a truncate method to the items and children types and making sure that callers use truncate instead of something like items := items[:i]. truncate() sets all the items past the end of the slice to nil allowing them to be GCed.

Copy link
Collaborator

@gconnell gconnell left a comment

Choose a reason for hiding this comment

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

Could you run the benchmarks and add a comment regarding how they change based on this pull?

// truncate truncates this instance at index so that it contains only the
// first index children. index must be less than or equal to length.
func (s *children) truncate(index int) {
l := len(*s)
Copy link
Collaborator

@gconnell gconnell Oct 5, 2016

Choose a reason for hiding this comment

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

Same comment as above, re: copy() and loop unrolling.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done with similar modifications as above.

@@ -153,6 +155,16 @@ func (s *items) pop() (out Item) {
return
}

// truncate truncates this instance at index so that it contains only the
// first index items. index must be less than or equal to length.
func (s *items) truncate(index int) {
Copy link
Collaborator

@gconnell gconnell Oct 5, 2016

Choose a reason for hiding this comment

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

What do you think of something like this, to unroll the loop a bit?

// at global scope
var nullItems = make(items, 16)

func (s *items) truncate(index int) {
  *s, toClear := (*s)[:index], (*s)[index:]
  for len(toClear) > 0 {
    toClear = toClear[copy(toClear, nullItems):]
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Except I had to add "var toClear items" and change := to = to make compiler happy.
Very clever code. Thank you.

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 also changed "nullItems" to "nilItems" since "null" reminds me of JAVA :-)

@keep94
Copy link
Contributor Author

keep94 commented Oct 5, 2016

I see no significant change in Insert, Delete, or Get.

benchmarkAscend seems to run slightly faster with my PR (230us vs 250us).

I see no significant change with the other Ascend/Descend benchmarks.

I don't understand why benchmarkAscend would run faster with my PR as ascending the btree is a read-only operation and shouldn't be splitting nodes or touching the freelist.

@keep94
Copy link
Contributor Author

keep94 commented Oct 5, 2016

Thanks for the comments. Sorry I didn't see them before. Very clever code you proposed. I integrated your changes and reran the benchmarks. I saw no significant change in the performance of insert and delete.

@keep94
Copy link
Contributor Author

keep94 commented Oct 5, 2016

BenchmarkAscend still runs faster with this PR (220us vs 250us) I don't understand why.

@gconnell gconnell merged commit 925471a into google:master Oct 5, 2016
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Nov 6, 2018
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Nov 13, 2018
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Nov 13, 2018
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Nov 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants