Boost C++ Libraries: Ticket #11647: add cleanup expired connections API https://svn.boost.org/trac10/ticket/11647 <p> when use signals2 with tracked shared object, it will cause memory leak when the shared track object which is allocated with allocated_shared() or make_shared() is destructed </p> <p> another problem is: after the shared track object is destructed, signals2::connection::connected() will return false, and signals2::connection::disconnect() will do nothing </p> <p> according to signals2's code, expired connection cleanup will happen after operator() is called, and maybe happen when signal.connect() is called. <strong>there is a problem when the signal is rarely emited, which means the time between successive operator() calls is long<em> </em></strong></p> <p> I have tried boost 1.59.0, expired connection cause memory leak is still a problem. </p> <p> I suggested to add an explicit cleanup API to signals2::signal class to let the user cleanup expired connections explicitly </p> <p> or <strong>if you think add such an API is not a must, may be you can add a comment in boost.signals2 document to warn the users that there may be memory leak.</strong> </p> <h2 class="section" id="make_sharedandallocated_sharedinboost">make_shared() and allocated_shared() in boost</h2> <p> document can be found at <a href="http://www.boost.org/doc/libs/1_59_0/libs/smart_ptr/make_shared.html">http://www.boost.org/doc/libs/1_59_0/libs/smart_ptr/make_shared.html</a> </p> <p> it is explicitly said these two function templates will use a single allocation, <strong>eliminating a significant portion of shared_ptr's construction overhead. This eliminates one of the major efficiency complaints about shared_ptr</strong> </p> <h2 class="section" id="make_sharedandallocated_sharedinC11standardspec">make_shared() and allocated_shared() in C++11 standard spec =</h2> <p> in C++11 standard section 20.7.2.2.6.6 at page 573: <strong>Implementations are encouraged, but not required, to perform no more than one memory allocation.</strong> </p> <h2 class="section" id="make_sharedandallocated_sharedinCompilerimplementations">make_shared() and allocated_shared() in Compiler implementations</h2> <p> as far as I know, GCC, CLang and Microsoft Visual Studio all use <strong>single allocation<em> </em></strong></p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11647 Trac 1.4.3 Frank Mori Hess Sun, 13 Sep 2015 23:15:22 GMT <link>https://svn.boost.org/trac10/ticket/11647#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11647#comment:1</guid> <description> <p> Are you sure you are using 1.59? Because when I run the test program from your previous ticket against git develop branch (1.59 should behave similarly), I get the following, which shows the memory getting deallocated the first time you call connected() after the tracked object is destroyed. </p> <pre class="wiki">---TestCase2: check signal2 will prevent memory from being freed--- allocate 1 objects, object size is 72 construct TrackObject ---TestCase2: after registerHandler: conn.connected: 1 signal triggered destruct TrackObject ---TestCase2: should free trackobj here, but not--- deallocate 1 objects ---TestCase2: connected: 0 ---TestCase2: connected() shows that it's already disconnected --TestCase2: so, conn.disconnect() does nothing, the memory is still not freed ---TestCase2: only re-trigger will free memory before this line --- </pre> </description> <category>Ticket</category> </item> <item> <author>Lutts Cao <lutts.cao@…></author> <pubDate>Mon, 14 Sep 2015 02:16:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11647#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11647#comment:2</guid> <description> <p> Sorry, I just checked I STILL use 1.56 which is installed in my system, not 1.59.0 which is build my self </p> <p> Seems you must call some method on signals2::connection or signals2::signal to cleanup the expired connections, for example, call connection.connected() or signal.num_slots() </p> <p> But this implicit behavior is not documented, <strong>I suggest add some comment in the document</strong> </p> <p> Thanks for your work! </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11647#comment:1" title="Comment 1">fmhess</a>: </p> <blockquote class="citation"> <p> Are you sure you are using 1.59? Because when I run the test program from your previous ticket against git develop branch (1.59 should behave similarly), I get the following, which shows the memory getting deallocated the first time you call connected() after the tracked object is destroyed. </p> <pre class="wiki">---TestCase2: check signal2 will prevent memory from being freed--- allocate 1 objects, object size is 72 construct TrackObject ---TestCase2: after registerHandler: conn.connected: 1 signal triggered destruct TrackObject ---TestCase2: should free trackobj here, but not--- deallocate 1 objects ---TestCase2: connected: 0 ---TestCase2: connected() shows that it's already disconnected --TestCase2: so, conn.disconnect() does nothing, the memory is still not freed ---TestCase2: only re-trigger will free memory before this line --- </pre></blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Frank Mori Hess</dc:creator> <pubDate>Thu, 24 Sep 2015 23:38:48 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11647#comment:3 https://svn.boost.org/trac10/ticket/11647#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">worksforme</span> </li> </ul> Ticket