Review of a safer memory management approach for C++?

Hello Boost developers, I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code. The technical report for the approach is: Teuchos C++ Memory Management Classes, Idioms, and Related Topics The Complete Reference A Comprehensive Strategy for Safe and Efficient Memory Management in C++ for High Performance Computing and can be found at: http://www.cs.sandia.gov/~rabartl/TeuchosMemoryManagementSAND.pdf If someone would be willing to at least go through the abbreviated table of contents laid out in the Preface and provide some feedback, I would be greatly appreciative. If there is a better mail list to send this too, please let me know. Thanks, - Ross P.S. Please make sure and respond to me personally (rabartl@sandia.gov<mailto:rabartl@sandia.gov>) or a spam filter will likely kill it. ----------------------------------------------------------------------- Dr. Roscoe A. Bartlett Sandia National Laboratories Department of Optimization and Uncertainty Estimation Trilinos Software Engineering Technologies and Integration Lead (505) 844-5097

Bartlett, Roscoe A wrote:
Hello Boost developers,
I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code. The technical report for the approach is:
Teuchos C++ Memory Management Classes, Idioms, and Related Topics The Complete Reference A Comprehensive Strategy for Safe and Efficient Memory Management in C++ for High Performance Computing
and can be found at:
http://www.cs.sandia.gov/~rabartl/TeuchosMemoryManagementSAND.pdf
If someone would be willing to at least go through the abbreviated table of contents laid out in the Preface and provide some feedback, I would be greatly appreciative.
I note that there is no thread safety baked in yet. You can use boost::range instead of a reference to vector to pass an array safely. It isn't clear to me what your implementation offers that isn't covered by purify or library checked iterators. If you do your own allocator you need to do these things to implement a debug mode. If you use the system allocator them purify works. If you use the stl then you use their debug mode. I don't see the point of implementing your own reference counted allocator and pointer object to replace the system allocator and raw pointer when that is the case where tools like valgrind and purify work. I read your justification for why these tools are insufficient, but you didn't convince me that you have covered any cases that they would not. It seems to me that you have invented a way to do manually what valgrind does automatically. What am I missing? Regards, Luke

Lucanus,
-----Original Message----- From: Simonson, Lucanus J [mailto:lucanus.j.simonson@intel.com] Sent: Wednesday, May 26, 2010 6:28 PM To: boost@lists.boost.org Cc: Bartlett, Roscoe A Subject: RE: Review of a safer memory management approach for C++?
Bartlett, Roscoe A wrote:
Hello Boost developers,
I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code. The technical report for the approach is:
Teuchos C++ Memory Management Classes, Idioms, and Related Topics The Complete Reference A Comprehensive Strategy for Safe and Efficient Memory Management in C++ for High Performance Computing
and can be found at:
http://www.cs.sandia.gov/~rabartl/TeuchosMemoryManagementSAND.pdf
If someone would be willing to at least go through the abbreviated table of contents laid out in the Preface and provide some feedback, I would be greatly appreciative.
I note that there is no thread safety baked in yet.
[Bartlett, Roscoe A] As noted in Section 5.14, thread safety has not been needed in our CSE codes yet, at least not involving something as high-level as a smart pointer. Also, I am not convinced that *every* RCP object should be thread safe. I think there are other alternatives that will yield safe code with lower overall overhead.
You can use boost::range instead of a reference to vector to pass an array safely.
[Bartlett, Roscoe A] You can't template a virtual function in an abstract interface on a Range type. That means you can't use runtime polymorphism. Are you suggesting that large application codes template their entire code base on Range types? That is a very bad idea. Unnecessary templating results in all types of problems such as object code bloat, long (or intractable in many cases I have seen) compile times, usability problems (e.g. SomeClass<A,B,C,...,X,Y,Z>), compatibility problems (e.g. Type<A> not compatible with Type<B>), etc. For any non-trivial code, implicit template instantiation is not even feasible (i.e. the compiler segfaults (e.g. the Sun) or just never finishes) and we have to result to tedious and hard to maintain explicit instantiation. There are some programming problems where templating is the best way to solve the problem but replacing: double * x, size_t s_size with a templated object is not one of them, not by a long way. Remember, all we are really trying to do is to replace the lowest level uses of (T*, size_t) with a safe alternative. We don't need (and can't afford) the full flexibility of a templated iterator type.
It isn't clear to me what your implementation offers that isn't covered by purify or library checked iterators. If you do your own allocator you need to do these things to implement a debug mode. If you use the system allocator them purify works. If you use the stl then you use their debug mode.
[Bartlett, Roscoe A] A lot of data that gets allocated in a CSE application is not and cannot get allocated with STL allocators. As for Purify, that is not a sufficient solution either for the reasons described in Section 3.2 and Section 5.11.5. Also, Purify is a commercial product and may CSE developers simply don't have access to it (and would not know how to use it if they did is some cases).
I don't see the point of implementing your own reference counted allocator and pointer object to replace the system allocator and raw pointer when that is the case where tools like valgrind and purify work. I read your justification for why these tools are insufficient, but you didn't convince me that you have covered any cases that they would not. It seems to me that you have invented a way to do manually what valgrind does automatically. What am I missing?
[Bartlett, Roscoe A] Reference counting in ArrayRCP is critical for maintaining persisting associations (see Section 4.2 and other material), iterators can't do this. Again, valgrind and purify have many issues and they will *never* catch the types of semantic memory usage errors described in Section 3.2. The Teuchos Memory Management classes trivially catch many of these types of semantic usage errors. If you put together the fact that you can't manage full templating of every large code bases on Range types and accept the fundamental short comings of memory checking tools, can you see the motivation for this approach? I would be curious what opinions you have of some of the other material (such as design implications of the runtime handling of weak pointers). Thanks, - Ross

Did you consider using type erasure (e.g. boost::function, http://stlab.adobe.com/classadobe_1_1any__iterator.html, etc.) ? -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com

On 05/26/10 17:37, Bartlett, Roscoe A wrote:
Hello Boost developers, [snip] pointers in high-level code. The technical report for the approach is:
Teuchos C++ Memory Management Classes, Idioms, and Related Topics The Complete Reference A Comprehensive Strategy for Safe and Efficient Memory Management in C++ for High Performance Computing
and can be found at:
http://www.cs.sandia.gov/~rabartl/TeuchosMemoryManagementSAND.pdf
[snip] Page 24 contains: ill-conceived ability to implicitly convert arrays of derived types to arrays of base types. There only one problem with doing that that I can think of and that's the difference in sizes which would lead to operator++ for base array possibly pointing to the middle of an object of the derived type. However, couldn't that be overcome by wrapping the container in something that adjusted the operator++ to increment the pointer by the derived type size while returning a pointer to the base type? Also, the table on that page just mentions Array's. What about all other stl types which are implemented using pointers (like std::list). How would one know whether or not the list elements contained elements that pointed to the same list object; thereby leading to a circular reference. How would that be handled?

On 05/26/10 17:37, Bartlett, Roscoe A wrote:
Hello Boost developers,
I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code. The technical report for the approach is:
Teuchos C++ Memory Management Classes, Idioms, and Related Topics The Complete Reference A Comprehensive Strategy for Safe and Efficient Memory Management in C++ for High Performance Computing
and can be found at:
http://www.cs.sandia.gov/~rabartl/TeuchosMemoryManagementSAND.pdf
Page 79 contains: there is no bullet-proof way to address circular references However, there's some titles with "cyclic reference counting" here: http://www.cs.kent.ac.uk/people/staff/rej/gcbib/gcbibL.html They have disadvantages; however, obviously some methods do exist; hence, "no bullet-proof" way seems a bit harsh to me.

Bartlett, Roscoe A wrote:
Hello Boost developers,
I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code.
Never use owning naked pointers and only use RAII (as is required for exception-safe programming anyway) with exclusive ownership and no aliasing, and you have no problems. Usage of shared_ptr should be an exception, not a widely deployed solution to memory management issues. Shared ownership is hard to reason about, and even if you use a similar cycle-aware solution, cycles remain a real problem (they prevent deterministic ordered destruction of objects, meaning they're only applicable to certain classes of objects).

if I understand "hard to reason about" in the right why : like there is no need for shared ownership at all, this also means that there is no use for COM Programming - and of course there is. Raw resp. opaque pointers have one huge advantage in productive environments : They work as perfect isolators, removing any compile time dependencies. And from my point of view, compile time is what matters most, if you go productive, otherwise you end up waiting for recompiles. From: Mathias Gaunard <mathias.gaunard@ens-lyon.org> To: boost@lists.boost.org Date: 27.05.2010 14:59 Subject: Re: [boost] Review of a safer memory management approach for C++? Sent by: boost-bounces@lists.boost.org Bartlett, Roscoe A wrote:
Hello Boost developers,
I am interested in finding one or more individuals who are knowledgeable about memory management in C++ (and especially of the reference-counting approach taken by boost::shared_ptr and boost::weak_ptr) to review an idea for a comprehensive approach to safer memory management in C++ that encapsulates all raw C++ pointers in high-level code.
Never use owning naked pointers and only use RAII (as is required for exception-safe programming anyway) with exclusive ownership and no aliasing, and you have no problems. Usage of shared_ptr should be an exception, not a widely deployed solution to memory management issues. Shared ownership is hard to reason about, and even if you use a similar cycle-aware solution, cycles remain a real problem (they prevent deterministic ordered destruction of objects, meaning they're only applicable to certain classes of objects). _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Ingo Loehken wrote:
if I understand "hard to reason about" in the right why
Aliasing already makes programs hard to reason about, and albeit this is mostly known as an optimizer problem rather than a human one, it does make changes to state hard to track. Sharing ownership means it also becomes difficult to tell what the lifetime of an object is.
there is no need for shared ownership at all
I didn't say it wasn't needed; just that you shouldn't apply it to everything as a silver bullet fixing your memory management problems. There are other ways to do memory management well with exclusive ownership.

At Thu, 27 May 2010 20:02:45 +0200, Ingo Loehken wrote:
if I understand "hard to reason about" in the right why : like there is no need for shared ownership at all, this also means that there is no use for COM Programming - and of course there is.
I think you don't understand it the right way. Shared ownership (at least in the presence of mutation) is hard to reason about because seemingly-local modifications can have non-local effects. Furthermore, your logic seems flawed to me. By analogy: There is no need for Intel processors (we can all use AMD). Therefore there is no use for an Intel processor? -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com

No, thats a twisted interpretation. I'm just pointing out, there is a need for shared ownership. I am not discouraging any other approaches, because - as you state- there are multiple use cases. Besides that, I would be pleased to review the mentioned approach. Best regards, ILo. From: David Abrahams <dave@boostpro.com> To: boost@lists.boost.org Date: 27.05.2010 20:43 Subject: Re: [boost] Review of a safer memory management approach for C++? Sent by: boost-bounces@lists.boost.org At Thu, 27 May 2010 20:02:45 +0200, Ingo Loehken wrote:
if I understand "hard to reason about" in the right why : like there is no need for shared ownership at all, this also means that there is no use for COM Programming - and of course there is.
I think you don't understand it the right way. Shared ownership (at least in the presence of mutation) is hard to reason about because seemingly-local modifications can have non-local effects. Furthermore, your logic seems flawed to me. By analogy: There is no need for Intel processors (we can all use AMD). Therefore there is no use for an Intel processor? -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

[Please don't top post. Try outlook-quotefix or oe-quotefix: http://home.in.tum.de/~jain/software/outlook-quotefix/, http://home.in.tum.de/~jain/software/oe-quotefix/ ] At Fri, 28 May 2010 15:32:22 +0200, Ingo Loehken wrote:
From: David Abrahams <dave@boostpro.com>
Furthermore, your logic seems flawed to me. By analogy:
There is no need for Intel processors (we can all use AMD). Therefore there is no use for an Intel processor?
No, thats a twisted interpretation. I'm just pointing out, there is a need for shared ownership.
I'm not sure I agree that there actually is a need. All the shared ownership scenarios I can think of can be translated into single-ownership-at-a-higher-level. That, however, is not always convenient. -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com

How about resources shared across multiple instances, where the shared resource is hold by a static to a weak_ptr and each instance participating to that resource holds it as a shared ptr, to guarantee that there is no lifetime prolongation (same as approach for std::cout and others). Assumption for above statement : Construction of the resource is quite expensive. Another limitation, is if you do not have the choice. Relying on other frameworks, passing around objects with embedded reference counts, to enable sharing across language barriers, such like done by XPCOM in Mozilla between JS and C++ via idl. From: David Abrahams <dave@boostpro.com> To: boost@lists.boost.org Date: 28.05.2010 16:11 Subject: Re: [boost] Review of a safer memory management approach for C++? Sent by: boost-bounces@lists.boost.org [Please don't top post. Try outlook-quotefix or oe-quotefix: http://home.in.tum.de/~jain/software/outlook-quotefix/, http://home.in.tum.de/~jain/software/oe-quotefix/ ] At Fri, 28 May 2010 15:32:22 +0200, Ingo Loehken wrote:
From: David Abrahams <dave@boostpro.com>
Furthermore, your logic seems flawed to me. By analogy:
There is no need for Intel processors (we can all use AMD). Therefore there is no use for an Intel processor?
No, thats a twisted interpretation. I'm just pointing out, there is a need for shared ownership.
I'm not sure I agree that there actually is a need. All the shared ownership scenarios I can think of can be translated into single-ownership-at-a-higher-level. That, however, is not always convenient. -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (6)
-
Bartlett, Roscoe A
-
David Abrahams
-
Ingo Loehken
-
Larry Evans
-
Mathias Gaunard
-
Simonson, Lucanus J