-
Notifications
You must be signed in to change notification settings - Fork 938
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 leaks / ClassLoader SEVERE warnings #1104
Conversation
Next issue is that the RobotModelPtr that was passed to the OMPL plugin, is not fully released. |
9d6d0e6
to
8ec0d0a
Compare
Do you propose to leave this pull-request open? I would say it makes more sense to merge all the problems we find but have one issue to refer to... |
Yes, I intended this PR as open to all contributors willing to tackle some of the mentioned issues ;-) |
Related to #150 (comment), #150 (comment). |
Fixed two other bugs:
|
@@ -239,8 +233,9 @@ class KinematicsPluginLoader::KinematicsLoaderImpl | |||
std::map<std::string, std::vector<std::string> > iksolver_to_tip_links_; // a map between each ik solver and a vector | |||
// of custom-specified tip link(s) | |||
std::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase> > kinematics_loader_; | |||
std::map<const robot_model::JointModelGroup*, std::vector<kinematics::KinematicsBasePtr> > instances_; | |||
std::map<const robot_model::JointModelGroup*, kinematics::KinematicsBasePtr> instances_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the impression that multiple plugins can be loaded for the same JointModelGroup* (for whatever reason). This seems to change that. Is that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I only explained the reasoning for this in #150 (comment)
The KinematicsPluginLoader caches created kinematics solver (KS) instances. But the cache only maintains unique instances - they are not shared. The only purpose of the cache is to not allocate a KS twice in a row - once for validating that it is suitable for JMG here and once for actual use here.
Eventually, the JMG owns the created KS instance. KPL only caches it for short term.
As I got the very same impression as @simonschmeisser in the first place, I decided to emphasize the fact that this is only short-term cache by changing the data structure - only the last created KS instance is held per JMG (and passed on to the caller in the 2nd call in a row).
This also resolves a potential issue with dangling shared_ptrs in the cache (which usually should only be weak_ptrs for this reason).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a side note: Indeed each JMG owns its unique solver instance. This helps to avoid race conditions when using them from multiple threads in parallel.
b7c3461
to
60ff421
Compare
60ff421
to
66d07e2
Compare
66d07e2
to
4e9f65a
Compare
Tracked down next bug: |
540c553
to
bfb0964
Compare
bfb0964
to
6167e7c
Compare
Rebased to resolve conflicts. |
6167e7c
to
44b03ed
Compare
Ping @v4hn. I would like to merge this into the next release. |
gimme a break, I spent all day looking through requests. I will try to address more open requests tomorrow. |
@v4hn Ping. |
use of pluginlib's createUnmanagedInstance() is strongly discouraged: http://wiki.ros.org/class_loader#Understanding_Loading_and_Unloading
@v4hn I just found another improvement. Working on it later. Please do not yet merge immediately. |
44b03ed
to
59f2625
Compare
SharedStorage acts as a cache for several shared_ptrs. However, a cache should always store its pointers as weak_ptrs!
59f2625
to
9e1e088
Compare
ompl_simple_setup_ is stored in ModelBasedPlanningContextSpecification. Additionally a functor was passed to ompl_simple_setup_, storing a copy of the spec (and thus the shared_ptr). Resolved, by storing a const reference only.
9e1e088
to
ed3f4b4
Compare
Turned out, that the main bug for classloader issues was a circular reference in the OMPL wrapper: ed3f4b4 |
Sorry for not looking through this in time. Post-merge the changes seem valid and I would have merged. At the same time I really don't think it's a good idea to merge architecture changes in memory management (changing shared for weak ptrs, etc) an hour before a release. |
These changes are more than a month old and I'm running this code in production since then. I wasn't afraid at all ;-) |
Yes, you run it in your environment. In this case I agree post-merge, so we would have merged (& released) it either way.. |
Touché. |
When move_group node finishes, there are always warnings like:
This is a hint that managed plugin instances are not correctly released before the corresponding plugin loader is. Even worse, MoveIt still used a lot of pointers created unmanaged, where we wouldn't even notice such issues. For this reason, use of pluginlib's createUnmanagedInstance() is strongly discouraged:
http://wiki.ros.org/class_loader#Understanding_Loading_and_Unloading
This PR is to be considered as an open branch to contribute to fixing these issues. I started by replacing
createUnmanagedInstance()
withcreateUniqueInstance()
, which is available for C++11.I tracked down one issue already: The PlanningScenePtr passed to the
ompl_simple_setup_
viaob::GoalPtr
inModelBasedPlanningContext::setGoalConstraints()
was never released. This is an issue in OMPL.As a quick fix, I changed the
ConstraintSampler
to hold a rawPlanningScene*
instead of ashared_ptr
.This solved the memory leak: the
PlanningScene
instance is correctly released.However, it's not a clean solution: There is no chance to validate the pointer before use. I suggest to use a
weak_ptr
instead, makingscene_
private and only accessible viagetPlanningScene()
, which in turn could validate the weak pointer and issue an error msg (before eventually crashing).Please keep commit history when merging.