Re: [osg-users] A very simple ref_ptr memory leak example.
Thanks Simon, I think you are right. In my application, the member pointers causing the problem are really 'users' rather than 'owners'. One of my objectives is to protect myself from my own programming, and so avoiding raw pointers and moving into a style of programming that is more like Java or C# helps me a lot. If I had noticed the existance of osg::observer_ptr earlier, I think maybe I would have used it instead of ref_ptr for the class members in this case, and thus avoided the problem. On the other hand, if I had done that, my understanding of the problem would now be less complete ;-) Chris. Date: Tue, 18 Nov 2008 23:37:00 + From: Simon Hammett [EMAIL PROTECTED] Subject: Re: [osg-users] A very simple ref_ptr memory leak example. To: OpenSceneGraph Users osg-users@lists.openscenegraph.org Message-ID: [EMAIL PROTECTED] Content-Type: text/plain; charset=ISO-8859-1 Don't forget that these reference counted pointers (of all types) actually conflate two completely different concepts. That is: Ownership - vs - Uses / Has a relationship with If you break down your use of these pointers into these two concepts it's usually easy to work out what to do. Many objects make use of many different other objects, but ownership is usually a much more straight forward proposition. i.e. It rarely makes sense for object A to own object B and object B to own object A. but it's quite common for A to use B and B to use A. In general, use ref_ptr for owner ship and raw pointer (or better yet references) for uses. Of course there are exceptions to every rule of thumb, but the only times I've seen significant differences are when people are implementing interpreted languages and other relatively obscure corner cases. -- The truth is out there. Usually in header files. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] A very simple ref_ptr memory leak example.
I'm probably treading very old ground here to do with circular usage of ref_ptr, but it's new to me and I couldn't find any references in the mail archive about users with similar problems. I have pasted below, a very simple example of my usage of ref_ptr that leaks memory. I can see why it leaks and the destructors are never called, but I am looking for any good tips on how best to guard against such a scenario. Do I need to use weak ref pointers to implement this scenario properly? Can that be done with ref_ptr? I could call unref but that seems like a bad idea. It seemed such an easy trap to fall into, I wondered why it doesn't crop up more often? And if it does, how others have dealt with circular problems of this type in OSG? Chris Denham //-- #include osg/ref_ptr #include osg/Referenced #include iostream int main(int argc, char* argv[]) { struct B; struct A : public osg::Referenced { ~A() { std::cout A::~A() called std::endl; } osg::ref_ptrB b; }; struct B : public osg::Referenced { ~B() { std::cout B::~B() called std::endl; } osg::ref_ptrA a; }; osg::ref_ptrA a = new A(); osg::ref_ptrB b = new B(); a-b = b; b-a = a; return 0; } ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Try using virtual protected destructors ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Thanks, but that is not the problem. They are already implicitly virtual because of inheriting from Referenced. And protecting destructors will only help preventing making the Referenced derived objects on the stack... which I'm not doing here. I've just discovered osg::observer_ptr, so I'm having a look at that. Looks like it may be the ticket! Cheers. Chris. - Original Message - From: Enrique Parodi To: Chris Denham ; OpenSceneGraph Users Sent: Tuesday, November 18, 2008 5:26 PM Subject: Re: [osg-users] A very simple ref_ptr memory leak example. Try using virtual protected destructors ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
What compiler are you using? The snippet doesn't compile for me with gcc 4.1.2. It's not hard indeed to create cycles, and handling them robustly would mean checking for every reference stored in a Referenced instance if there isn't a cycle. Which is not impossible, but adds a lot of overhead I suspect. See Caveat #4 in http://andesengineering.com/OSG_ProducerArticles/RefPointers/RefPointers.html Paul Chris Denham wrote: I'm probably treading very old ground here to do with circular usage of ref_ptr, but it's new to me and I couldn't find any references in the mail archive about users with similar problems. I have pasted below, a very simple example of my usage of ref_ptr that leaks memory. I can see why it leaks and the destructors are never called, but I am looking for any good tips on how best to guard against such a scenario. Do I need to use weak ref pointers to implement this scenario properly? Can that be done with ref_ptr? I could call unref but that seems like a bad idea. It seemed such an easy trap to fall into, I wondered why it doesn't crop up more often? And if it does, how others have dealt with circular problems of this type in OSG? Chris Denham //-- #include osg/ref_ptr #include osg/Referenced #include iostream int main(int argc, char* argv[]) { struct B; struct A : public osg::Referenced { ~A() { std::cout A::~A() called std::endl; } osg::ref_ptrB b; }; struct B : public osg::Referenced { ~B() { std::cout B::~B() called std::endl; } osg::ref_ptrA a; }; osg::ref_ptrA a = new A(); osg::ref_ptrB b = new B(); a-b = b; b-a = a; return 0; } ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Hmm, not sure why it wouldn't compile for you, I'm using VisualStudio 2005 with OSG 2.6. Thanks for the link. Chris. - Original Message - From: Paul Melis [EMAIL PROTECTED] To: Chris Denham [EMAIL PROTECTED]; OpenSceneGraph Users osg-users@lists.openscenegraph.org Sent: Tuesday, November 18, 2008 5:37 PM Subject: Re: [osg-users] A very simple ref_ptr memory leak example. What compiler are you using? The snippet doesn't compile for me with gcc 4.1.2. It's not hard indeed to create cycles, and handling them robustly would mean checking for every reference stored in a Referenced instance if there isn't a cycle. Which is not impossible, but adds a lot of overhead I suspect. See Caveat #4 in http://andesengineering.com/OSG_ProducerArticles/RefPointers/RefPointers.html Paul Chris Denham wrote: I'm probably treading very old ground here to do with circular usage of ref_ptr, but it's new to me and I couldn't find any references in the mail archive about users with similar problems. I have pasted below, a very simple example of my usage of ref_ptr that leaks memory. I can see why it leaks and the destructors are never called, but I am looking for any good tips on how best to guard against such a scenario. Do I need to use weak ref pointers to implement this scenario properly? Can that be done with ref_ptr? I could call unref but that seems like a bad idea. It seemed such an easy trap to fall into, I wondered why it doesn't crop up more often? And if it does, how others have dealt with circular problems of this type in OSG? Chris Denham //-- #include osg/ref_ptr #include osg/Referenced #include iostream int main(int argc, char* argv[]) { struct B; struct A : public osg::Referenced { ~A() { std::cout A::~A() called std::endl; } osg::ref_ptrB b; }; struct B : public osg::Referenced { ~B() { std::cout B::~B() called std::endl; } osg::ref_ptrA a; }; osg::ref_ptrA a = new A(); osg::ref_ptrB b = new B(); a-b = b; b-a = a; return 0; } ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Hi Chris, Using ref_ptr's is far cheaper than a garbage collector we don't have (... until ISO C++ 2009 ?). osg::observer_ptr could be used to solve the problem, but you can also simply try to avoid circular references... how ? Well, you could try to define an object to be slave of another one. For instance, if 'B' is slave, then A has a ref_ptr to B, and B has only a raw pointer (A*). In most cases it's enough because the raw pointer is used only when A is allocated. Sukender PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/ Le Tue, 18 Nov 2008 18:22:13 +0100, Chris Denham [EMAIL PROTECTED] a écrit: I'm probably treading very old ground here to do with circular usage of ref_ptr, but it's new to me and I couldn't find any references in the mail archive about users with similar problems. I have pasted below, a very simple example of my usage of ref_ptr that leaks memory. I can see why it leaks and the destructors are never called, but I am looking for any good tips on how best to guard against such a scenario. Do I need to use weak ref pointers to implement this scenario properly? Can that be done with ref_ptr? I could call unref but that seems like a bad idea. It seemed such an easy trap to fall into, I wondered why it doesn't crop up more often? And if it does, how others have dealt with circular problems of this type in OSG? Chris Denham //-- #include osg/ref_ptr #include osg/Referenced #include iostream int main(int argc, char* argv[]) { struct B; struct A : public osg::Referenced { ~A() { std::cout A::~A() called std::endl; } osg::ref_ptrB b; }; struct B : public osg::Referenced { ~B() { std::cout B::~B() called std::endl; } osg::ref_ptrA a; }; osg::ref_ptrA a = new A(); osg::ref_ptrB b = new B(); a-b = b; b-a = a; return 0; } ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Using ref_ptr's is far cheaper than a garbage collector we don't have (... until ISO C++ 2009 ?). osg::observer_ptr could be used to solve the problem, but you can also simply try to avoid circular references... how ? Well, you could try to define an object to be slave of another one. For instance, if 'B' is slave, then A has a ref_ptr to B, and B has only a raw pointer (A*). In most cases it's enough because the raw pointer is used only when A is allocated. That's how I'd handle it. The posted code would behave the same for any type of reference-counted memory management system, I imagine, so isn't really an issue with OSG ref_ptr classes. It's simply an aspect of the algorithm, which programmers must be aware of and be careful to avoid. Or, to put it another way: I went to the doctor and said, 'hey doc, it hurts when I do this' and he replied 'don't do that'. :-) -Paul ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
The posted code would behave the same for any type of reference-counted memory management system, I imagine, so isn't really an issue with OSG ref_ptr classes. It's simply an aspect of the algorithm, which programmers must be aware of and be careful to avoid. Or, to put it another way: I went to the doctor and said, 'hey doc, it hurts when I do this' and he replied 'don't do that'. :-) -Paul Well, that's right: don't do that! And you're right, that would be the same for any ref pointers system. Ref pointers are a great solution that is in-between raw pointers and garbage collection. You just need to know how to use them... Note: You can have a look to boost smart pointers ( http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/smart_ptr.htm ), that's always interesting. Sukender PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/ ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] A very simple ref_ptr memory leak example.
Thanks for the tips everyone. I suppose as Paul suggests, it's best to avoid doing things that hurt. The problem is that when we accidentally implemented this pattern in a more complex application, it was a bit fiddly to track down. I only noticed the problem because of the memory leak that resulted from it. I suppose the lesson I learn is that I need to be more careful when using ref_ptr than blindly applying it to every Referenced object whose lifetime is less than obvious to me. Which I have to confess, was my previous rather flawed logic. Chris. Date: Tue, 18 Nov 2008 10:56:03 -0700 From: Paul Martz [EMAIL PROTECTED] Subject: Re: [osg-users] A very simple ref_ptr memory leak example. To: 'OpenSceneGraph Users' osg-users@lists.openscenegraph.org Message-ID: [EMAIL PROTECTED] Content-Type: text/plain; charset=us-ascii Using ref_ptr's is far cheaper than a garbage collector we don't have (... until ISO C++ 2009 ?). osg::observer_ptr could be used to solve the problem, but you can also simply try to avoid circular references... how ? Well, you could try to define an object to be slave of another one. For instance, if 'B' is slave, then A has a ref_ptr to B, and B has only a raw pointer (A*). In most cases it's enough because the raw pointer is used only when A is allocated. That's how I'd handle it. The posted code would behave the same for any type of reference-counted memory management system, I imagine, so isn't really an issue with OSG ref_ptr classes. It's simply an aspect of the algorithm, which programmers must be aware of and be careful to avoid. Or, to put it another way: I went to the doctor and said, 'hey doc, it hurts when I do this' and he replied 'don't do that'. :-) -Paul ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org