That sounds like progress, but from what you're describing I'm not sure you're actually testing C holding onto a reference to Ruby. As you say, swig is helping you out with the Ruby -> C direction, but we need to be able to make that void * reference actually point to a ruby object (that is not pointed to by any other ruby object) and still keep it alive. If you haven't had to integrate with the ruby GC system yet then there is a pretty good chance you aren't actually testing this. It can be a bit tricky to test for a couple reasons since a) you need to force the GC to run, and b) you need to ensure there are no other references to the ruby object that is being pointed to by the C object.
In fact now that I think about it, you really probably want a negative test to ensure that your testing strategy is working, i.e. keep tweaking your test until you get valgrind warnings telling you that you're accessing freed memory. Then enable the GC integration, and verify that those valgrind warnings go away. For more info on how to integrate with Ruby's GC you can read this article[1]. It's one of the few pieces of documentation I've found that actually explain how to keep a reference from C to a Ruby object. [1] http://clalance.blogspot.com/2013/11/writing-ruby-extensions-in-c-part-13.html --Rafael On Fri, Jan 23, 2015 at 9:01 AM, Darryl L. Pierce <dpie...@redhat.com> wrote: > On Thu, Jan 22, 2015 at 12:08:52PM -0500, Rafael Schloming wrote: > > The most important thing to get worked out for this is the memory > > management semantics between C and Ruby. From what I can tell from your > > branch, it looks like you haven't done that yet. > <snip> > > My initial readings into how Ruby handles object references initially > lead me to believe that, with Swig, we're receiving some benefit > already WRT object management. Since Ruby uses mark and sweep rather > than reference counts, when a Ruby object (or an C object wrapped by > Swig as a Ruby object) goes out of reference then it'll get garbage > collected. But I won't lie: there might be some subtle detail I'm > missing here. > > I played around with this last night after your suggestion and wrote > some stuff on a side branch [1]. It's a simple test that uses the > following types: > > * pn_rubyref_t - C type in Proton that's wrapped by Swig; holds a void * > reference to any kind of object > * Farkle - a pure Ruby class > > I then wrote a simple app that creates 1M instances of rb_rubyref_t and > 1M instances of Farkle as assigns a Farkle to each rb_rubyref_t. It then > puts them each into an array, which is size limited to 100k entries (to > allow any GC to run while the app is going). > > I also added finalizer function to Farkle that just outputs some text when > the object is being garbage collected. > > What I see as the app runs is the output of the Farkle instances being > garbage collected while there are still instances being created. > > The app then ends by sleeping and then exiting. > > Before and after sleeping the app outputs the number of objects (via > ObjectSpace) exist for each type. Running it multiple times I see all of > the pn_rubyref_t and Farkle instances being cleaned up, no memory > leaks. > > I then changed things to make a circular reference between Farkle and > pn_rubyref_t. Re-ran the tests and still see the objects getting cleaned > up. I also ran top to keep an eye on memory usage for the ruby-mri > process. > > O_o (1) [J:0/1028] mcpierce@mcpierce-laptop:cmake (0.3-fedora) $ top -b | > grep ruby-mri > 19989 mcpierce 20 0 188964 23228 6380 S 53.3 0.3 0:00.55 > ruby-mri > 19989 mcpierce 20 0 202644 36892 6380 S 18.3 0.5 0:01.10 > ruby-mri > 19989 mcpierce 20 0 207492 41784 6380 R 19.9 0.5 0:01.70 > ruby-mri > 19989 mcpierce 20 0 227748 62108 6380 S 17.6 0.8 0:02.23 > ruby-mri > 19989 mcpierce 20 0 229796 64020 6380 R 22.3 0.8 0:02.90 > ruby-mri > 19989 mcpierce 20 0 233096 67188 6380 R 57.1 0.8 0:03.42 > ruby-mri > 19989 mcpierce 20 0 233096 67188 6380 S 0.7 0.8 0:03.44 > ruby-mri > 19989 mcpierce 20 0 233096 67188 6380 S 0.0 0.8 0:03.44 > ruby-mri > 19989 mcpierce 20 0 233096 67188 6380 S 0.0 0.8 0:03.44 > ruby-mri > 19989 mcpierce 20 0 233096 67188 6380 S 1.3 0.8 0:03.48 > ruby-mri > 19989 mcpierce 20 0 235340 69564 6380 R 48.5 0.9 0:04.94 > ruby-mri > 19989 mcpierce 20 0 235340 69564 6380 S 47.5 0.9 0:06.37 > ruby-mri > 19989 mcpierce 20 0 235340 69564 6380 R 50.5 0.9 0:07.89 > ruby-mri > 19989 mcpierce 20 0 235340 69564 6380 S 48.0 0.9 0:09.34 > ruby-mri > > I only show those lines since, after that point, the virtual memory > footprint didn't grow for the run os the apps run. > > > [1] https://github.com/mcpierce/Proton/tree/c-to-ruby-reference-gc-check > > -- > Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. > Delivering value year after year. > Red Hat ranks #1 in value among software vendors. > http://www.redhat.com/promo/vendor/ > >