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 parameter system #1090

Merged
merged 2 commits into from
Jun 22, 2016
Merged

Fix memory leak in parameter system #1090

merged 2 commits into from
Jun 22, 2016

Conversation

jgosmann
Copy link
Collaborator

@jgosmann jgosmann commented Jun 11, 2016

Description:
Fixes #1089.

We create a weak reference to the key with a callback here that will free the value when no strong references to the key are left. To be able to do this we need the id of the key which will be retrieved
with the _ref2id dictionary. Note that weak reference use the hash function of the object they are referencing. Thus, we have to use the id of the weak reference to index that dictionary. Finally, to support
the del operation we need to be able to map the object id to the weak reference which requires another dictionary _id2ref (instantiating another weak ref would give us an object with a different id). This dictionary has another important function: It stores strong references the weak reference to ensure that the callback gets called (it would not if the weak reference gets garbage collected beforehand and we
need to store ids as keys in the _ref2id dictionary).

Motivation and context:
See #1089.

How has this been tested?
Added a unit test checking that values in the WeakKeyIDDictionary are cleaned up.

Where should a reviewer start?
Look at #1089 and the test to understand the problem, then look at the changes to WeakKeyIDDictionary and information above to see how this is fixed.

How long should this take to review?

  • Average (neither quick nor lengthy)

Types of changes:

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have read the CONTRIBUTING.rst document.
  • I have updated the documentation accordingly. -> no documentation changes required
  • I have included a changelog entry.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@jgosmann jgosmann added this to the 2.1.1 release milestone Jun 11, 2016
@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @tbekolay to be a potential reviewer

@tbekolay
Copy link
Member

tbekolay commented Jun 11, 2016

A callback! Well played, Python weakref API. This LGTM; nominating @hunse as the other reviewer as he wrote this class in the first place.

Also I think makes sense to squash to a single commit during the merge.

@tbekolay tbekolay mentioned this pull request Jun 11, 2016
12 tasks
@hunse
Copy link
Collaborator

hunse commented Jun 21, 2016

This code looks fine, but I don't quite understand why this whole thing is necessary. Why were things not getting garbage collected before, and how does this help?

@hunse
Copy link
Collaborator

hunse commented Jun 21, 2016

Oh, I see, the key was getting freed, but not the value? So we were just storing a bunch of extra values. Maybe put a comment to that effect somewhere, either when you make the callback or at the beginning of the callback.

@jgosmann
Copy link
Collaborator Author

Oh, I see, the key was getting freed, but not the value?

Yes.

Maybe put a comment to that effect somewhere

Isn't that the reviewer's task now given the PR review guide lines?

@hunse
Copy link
Collaborator

hunse commented Jun 22, 2016

Isn't that the reviewer's task now given the PR review guide lines?

Well, technically it's whoever has the time. I had to run earlier so I put it back to you. But I can do it tomorrow.

@hunse
Copy link
Collaborator

hunse commented Jun 22, 2016

@jgosmann: Does this look good?

@jgosmann
Copy link
Collaborator Author

LGTM 🍰

WeakKeyIDDictionary was not removing values when the key was freed.

We create a weak reference to the key with a callback here that will
free the value when no strong references to the key are left. To be
able to do this we need the id of the key which will be retrieved
with the _ref2id dictionary. Note that weak reference use the hash
function of the object they are referencing. Thus, we have to use the
id of the weak reference to index that dictionary. Finally, to support
the del operation we need to be able to map the object id to the weak
reference which requires another dictionary _id2ref (instantiating
another weak ref would give us an object with a different id). This
dictionary has another important function: It stores strong references
the weak reference to ensure that the callback gets called (it would
not if the weak reference gets garbage collected beforehand and we
need to store ids as keys in the _ref2id dictionary).

Fixes #1089.

Also added a test for WeakKeyIDDictionary value garbage collection.
@tbekolay
Copy link
Member

I'm happy to merge @hunse or you can go ahead; I'd squash it all down to one commit, I think.

@hunse
Copy link
Collaborator

hunse commented Jun 22, 2016

I'll merge.

Just one comment about commit messages: fd0bb32 has a very long commit message that goes into detail about why two dictionaries are used. This kind of documentation is useful, but I'm not sure if a commit message is the best place for it. If I'm working on that section of code, it's not likely that I'll see that message. I could do a git blame, but often one would need a second- or third-generation blame to get back to a message like that. For example, I added a commit here that fixes the function order, but that's going to make the blame for those important changes one generation older.

@hunse hunse merged commit 17b97be into master Jun 22, 2016
@hunse hunse deleted the fix-1089 branch June 22, 2016 15:04
@hunse
Copy link
Collaborator

hunse commented Jun 22, 2016

Also, I did keep the full commit message in the merge, so that comment was more of a general comment than something that we actually need to address here.

@tbekolay
Copy link
Member

I'd much rather have the documentation in the commit message than in the PR text... there's no downside to long commit messages because most tools will only show the summary line anyway. It's probably true that placing that documentation elsewhere would be good too, but I definitely don't want to discourage anyone from writing long commit messages, as that's definitely something that I read when looking at PRs commit-by-commit.

@tbekolay
Copy link
Member

But yeah, putting that information in the code itself is often preferable, I will agree on that :) 🌈 🐙

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Memory leak in parameter system.
4 participants