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

Auto close feature to improve memory management of option types. #57

Merged
merged 10 commits into from
Jun 28, 2024

Conversation

bhartnett
Copy link
Contributor

@bhartnett bhartnett commented Jun 27, 2024

This change reverts some of the changes from #48 which prevents the opts types from be closed when passed in. Currently in Nimbus the db opt types are not freed manually so there is a memory leak from what I can tell. This change should fix the problem once we roll this version into Nimbus.

Also doing a bit of cleanup and add a few more tests.

readOpts = ReadOptionsRef(nil),
writeOpts = WriteOptionsRef(nil),
txDbOpts = TransactionDbOptionsRef(nil),
readOpts = defaultReadOptions(),
Copy link
Member

Choose a reason for hiding this comment

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

if this is called without supplying readOpts/writeOpts, what happens? Who frees the options allocated by the default?

Copy link
Member

Choose a reason for hiding this comment

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

ie in the colfamily pr, the idea was that if nil is given, the temporary options instance is "owned" by the callee (beginTransaction in this case) and therefor it also deallocates it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They get freed when the db instance is closed. db.close() will free all the opts types regardless of whether passed in or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually the above comment applies in the other locations. In this instance the opts are freed when the transaction is closed.

Copy link
Member

Choose a reason for hiding this comment

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

what if the transaction/database/etc fails to open?

Copy link
Member

Choose a reason for hiding this comment

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

I think the core issue here is that when we do xxx = defaultOptions in the parameter list, the ownership is unclear which has these knock-on effects. semantically, it becomes strange that "sometimes" the function closes the passed-in options and sometimes it doesn't (if I pass in options, can I use them for another call? etc)

I'm not sure this is worth fixing, but it's certainly worth thinking about and the nil approach was a compromise (non-nil = caller owns) to get there.

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 actually found the solution using nil to be more unclear which is why I removed it. Using the default options solution makes it clear that the options will always get cleaned up when the database is closed. When using the nil method, the options require manual clean up if being passed in, if they don't get passed in then the options are cleaned up in the open function before the database is closed (this may cause other issues). The Java RocksDb library states ' Options instance should not be disposed before all DBs using this options instance have been closed', see here: https://javadoc.io/doc/org.rocksdb/rocksdbjni/latest/org/rocksdb/RocksDB.html#open-org.rocksdb.DBOptions-java.lang.String-java.util.List-java.util.List-

You should be able to use options for multiple calls as long as the database is open so for most of the functions that won't be a problem. In the case of beginTransaction these options get cleaned up when closing the transaction and so I guess this could be a problem if we want to reuse the opts across transactions. This function is not currently used in Nimbus by the way.

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'm not sure if we can use nim destructors with the refc garbage collector but perhaps in a future change we can use destructors to help cleanup the opts types and then don't close any opt types in db.close().

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if we can use nim destructors

no, these are ORC-only. we can indeed revisit the problem then - until then, perhaps it's worth documenting these quirks in the API as well, similar to java.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll add that.

I'm also working a change to support choosing if the types are freed when closing the database or not by adding a flag to each opt type. If you pass in an opt it won't get closed automatically but if none is passed in the default opts will get closed when the database is closed.

@bhartnett bhartnett changed the title Fix memory leak regression Auto close feature to improve memory management of option types. Jun 27, 2024
@bhartnett bhartnett requested a review from arnetheduck June 27, 2024 17:11
@bhartnett bhartnett merged commit 03313d8 into master Jun 28, 2024
10 checks passed
@bhartnett bhartnett deleted the fix-memory-leak-regression branch June 28, 2024 02:04
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