[C++-sig] alternative smart pointer (intrusive_ptr) example
jeff.webb at nta-inc.net
Mon Jul 28 17:53:34 CEST 2008
David Abrahams wrote:
> on Thu Jul 24 2008, Jeff Webb <jeff.webb-AT-nta-inc.net> wrote:
>> The boost::python library provides excellent support for wrapping C++
>> objects managed by boost::shared_ptr reference counting smart
>> pointers. I am attempting to achieve similar functionality with a
>> little less memory overhead by embedding the reference count in the
>> managed object and using boost::intrusive_ptr instead.
> Why? Have you profiled the memory use of shared_ptr and found it to be
> a problem?
I investigated the memory usage of shared_ptr by running valgrind on a test program and by looking at the shared_ptr source code. My findings are summarized in this post:
I am designing a C++ library from the ground up, so I am not tied to any existing conventions (base classes, memory management schemes, etc.). I want to be able to expose the fundamental building blocks of my library to python, but I want to allow the library to be used without python as well. I have decided to use smart pointers internally in my C++ library to lay the foundation for seamless integration with python. Some of my library building blocks are very small, and users will most likely have a large number of instances, so the overhead of the internal memory management scheme is a concern. I am less concerned by the overhead of the python wrappers, since I expect a small percentage of these objects to by wrapped by python at any given time.
It think that by using intrusive_ptr, I can save one raw pointer's worth of memory for every smart pointer I use, and another raw pointer's worth of memory (plus maybe an int) for the managed objects themselves.
I have included the highlights of my previous email below, but you can use the link above if you want to look at the full post. I would be interested in hearing any thoughts you may have on any of this.
-------- Original Message --------
Date: Thu, 17 Jul 2008 18:02:26 -0500
From: Jeff Webb <jeff.webb at nta-inc.net>
To: Development of Python/C++ integration <c++-sig at python.org>
Subject: shared_ptr vs. intrusive_ptr
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:
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.
int use_count_; (4 bytes)
int weak_count_; (4 bytes)
vtable pointer? (4 or 8 bytes)
X * (4 or 8 bytes)
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
More information about the Cplusplus-sig