[C++-sig] shared_ptr vs. intrusive_ptr
Jeff Webb
jeff.webb at nta-inc.net
Mon Jul 21 16:50:45 CEST 2008
Any comments? Surely someone has looked at the memory usage of shared_ptr. I'm not asking someone to verify the overhead down to the byte, but I would like to have confirmation that the numbers I posted are what one would generally expect, and that there is some motivation to pursue an alternative implementation in certain cases. If I am totally off-base here, or if no one else is interested in this issue, then I don't see any point in posting my proposed solution for review.
Jeff Webb wrote:
> Since we're discussing the topic of shared_ptr, intrusive_ptr, and other
> custom smart pointers, I have a few observations and some related
> questions that I would like to share. I would love to hear some
> comments from the experts on these.
>
> (1) It seems that if you are designing a C++ library from the ground up
> to use with boost::python, it makes a lot of sense to use smart pointers
> internally in your C++ library. Python uses reference counting to
> manage objects, so if you use reference counting in your C++ library,
> you are laying the foundation for a seamless python interface instead of
> fighting Python's memory management.
>
> (2) The boost::python support for shared_ptr is fantastic, and if you
> make good use of shared_ptrs, many things will 'just work'.
>
> (3) If you decide to use smart pointers, there are two main reasons
> *not* to use shared_ptr: (a) your library uses a custom smart pointer
> internally
> (b) the memory usage of shared_ptr is not acceptable
>
> I have attempted to quantify the memory usage of shared_ptr vs. a simple
> intrusive_ptr implementation using the attached test program. I used
> valgrind to verify the dynamic memory usage. Here are the results:
>
> shared_ptr
> ----------
>
> Each shared_ptr is the size of two raw pointers (one for the managed
> object, and one for the shared reference count):
>
> A total of 8 bytes on x86 or 16 bytes on x86_64
>
> For each object that is managed by shared_ptrs, a shared reference count
> must be allocated. The memory usage for the shared reference count
> appears to be two integers and two pointers:
>
> A total of 16 bytes on x86
> or 24 bytes on x86_64
>
> When looking at the shared_ptr source code, I could only find one
> pointer in the shared reference count, but I cannot reconcile this with
> the memory usage reported by valgrind. I suppose it doesn't really
> matter, but the breakdown I found in the code is listed below. Maybe I
> am not looking at the right implementation for my system.
>
> sp_counted_impl_p:
> sp_counted_base:
> int use_count_; (4 bytes)
> int weak_count_; (4 bytes)
> X * (4 or 8 bytes)
> ??? (4 or 8 bytes)
>
> intrusive_ptr
> -------------
>
> Each intrusive_ptr is the size of a raw pointer:
>
> A total of 4 bytes on x86 or 8 bytes on x86_64
>
> For each object that is being managed by this intrusive_ptr
> implementation, an extra integer must be added to the object to hold the
> reference count:
>
> A total of 4 bytes on x86 or x86_64
>
> (5) Summary: If you are wrapping a relatively small number of objects
> or you are wrapping very large objects, the overhead of shared_ptr is
> probably acceptable. If you are wrapping a large number of very small
> objects, then a custom intrusive_ptr solution is worth looking into.
>
> Any comments on these ideas? Is my summary of shared_ptr memory usage
> on target?
>
> Thanks,
>
> Jeff
More information about the Cplusplus-sig
mailing list