Hi Stephan,

I was struggling with a very similar issue; please see
http://groups.google.com/group/v8-users/browse_thread/thread/3d4e7e801bd58a0f#for
reference.

To make the long story short - V8 by default collects garbage only when
necessary; in my case with a simple (empty) testing class, this first
happened after creating approx. one to ten million (!) instances.

I would really appreciate some kind of moving forward in this issue. My
primary goal is to automatically close DB connections and this is somewhat
pressing in my scenario. However, it looks like there is no generic and
straightforward way to force GC.


O.


2009/3/5 Stephan Beal <[email protected]>

>
> Hi, all!
>
> After having bound hundreds of C-like functions i'm ready to bind my
> first class in v8. i've got it working so far except that my Weak
> Pointer callback isn't being triggered, and i have been unable to
> figure out why. i'm pasting the code here - it's a bit long, but i
> would really appreciate any insights on this, as i can't do ANY class-
> level wrapping until i figure out how to get the objects deleted
> properly.
>
> Most of the code below was based on suggestions from:
>  http://create.tpsitulsa.com/blog/2009/01/31/persistent-handles/
>  http://create.tpsitulsa.com/blog/2009/01/29/v8-objects/
>
> It's worth noting that the v8 sample code doesn't have any examples of
> weak pointers :(.
>
> The class i'm wrapping, PathFinder, can be considered opaque for our
> purposes - the binding to the object appears to work, it's just that
> my dtor (pf_dtor()) is never called.
>
> The functions listed below are:
>
>     - SetupPathFinderClass() sets up the class for JS-side access.
> Installs the ctor and class instance prototype
>     - pf_ctor() - the instance constructor
>     - pf_dtor() - the weak pointer callback
>     - pf_wrap() - associates a PathFinder JS object with a C++ object
> and does the Persistent/Weak voodoo.
>
> i've tried with and without HandleScopes, but the results are the same
> - pf_dtor() is never being called.
>
> The C++ code (JS code follows):
>
>
> #include <v8/PathFinder.h>
> #include <v8.h>
> #include <v8/v8-convert.h>
> #include <v8/v8-plugin.h>
>
> #include <iostream> /* only for debuggering */
> #ifndef CERR
> #define CERR std::cerr << __FILE__ << ":" << std::dec << __LINE__ <<
> " : "
> #endif
>
> namespace v8 { namespace p3 {
>    using namespace ::v8::bind;
>    using namespace ::v8::convert;
>
>    //static const void * pf_bind_cx() { static const int x=7;return
> &x;}
>
>    static void pf_dtor(Persistent< Value > object, void *parameter)
>    {
>        CERR << "pf_dtor() PathFinder @"<<parameter<<'\n';
>        PathFinder * pf = static_cast<PathFinder*>( parameter );
>        //UnbindNative( pf_bind_cx(), parameter, pf );
>        if( pf != &::v8::p3::plugin::PluginPath() )
>        {
>            delete pf;
>        }
>        object.Dispose();
>        object.Clear();
>    }
>
>    static Persistent<Object> pf_wrap( Handle<Object> _self,
> PathFinder * value )
>    {
>        //HandleScope scope;
>        //BindNative( pf_bind_cx(), value, value );
>        Persistent<Object> self( Persistent<Object>::New(_self) );
>        self.MakeWeak( value, pf_dtor );
>        self->SetInternalField(0,External::New(value));
>        self->Set(String::New("bogo"),String::New("bogo was here"));
>        CERR << "Wrapped PathFinder @"<<value<<" in a
> Persistent<Object>.\n";
>        //return scope.Close(self);
>        return self;
>    }
>    static Handle<Value> pf_ctor(const Arguments& argv)
>    {
>        if (!argv.IsConstructCall())
>            return ThrowException(String::New("Cannot call constructor as
> function"));
>
>        const int argc = argv.Length();
>        if( (1 == argc) && argv[0]->IsExternal() )
>        {
>            External * ex = External::Cast( *argv[0] );
>            if( ex )
>            {
>                return pf_wrap( argv.This(),
> static_cast<PathFinder*>(ex->Value
> ()) );
>            }
>            else
>            {
>                return ThrowException(String::New("First argument to ctor
> failed
> External::Cast()"));
>            }
>        }
>        //HandleScope hscope;
>        std::string a0 = (argc>0) ? JSToStdString(argv[0]) : "";
>        std::string a1 = (argc>1) ? JSToStdString(argv[1]) : "";
>        std::string a2 = (argc>2) ? JSToStdString(argv[2]) : "";
>        CERR << "PathFinder(["<<a0<<"], ["<<a1<<"], ["<<a2<<"])\n";
>        PathFinder * pf = new PathFinder( a0, a1, a2 );
>        //return hscope.Close( pf_wrap( argv.This(), pf ) );
>        return pf_wrap( argv.This(), pf );
>        //return hscope.Close( pf_wrap( argv.This(), pf ) );
>    }
>
>    Handle<Value> SetupPathFinderClass(const Handle<Object> target )
>    {
>        // Set up prototype:
>        Handle<FunctionTemplate> ctor = FunctionTemplate::New(pf_ctor);
>        Local<ObjectTemplate> objt = ctor->InstanceTemplate();
>        objt->SetInternalFieldCount(1);
>
>        // Install ctor:
>        Handle<Function> pffunc( ctor->GetFunction() );
>        target->Set(String::New("PathFinder"), pffunc );
>
>        // Install instance wrapping PluginPath() shared object:
>        Handle<Value> pfex( External::New( &::v8::p3::plugin::PluginPath
> () ) );
>        Handle<Object> pfobj = pffunc->NewInstance( 1, &pfex );
>        pffunc->Set(String::New("plugins"), pfobj );
>        return pfobj;
>    }
>
> }} // namespaces
>
>
> i've created hundreds of PathFinder objects in small scopes to try to
> force GC, but my debugging message in pf_dtor() never gets output:
>
> var my = {p:null};
> {
>    for( var i  = 0; i < 5; ++i )
>    {
>        var p = ['/usr/bin','/bin','~/bin'];
>        my.p = new PathFinder(p.join(''+i),"",""+i);
>        //delete my.p;
>    }
>    print('my.p=',my.p,typeof my.p,my.p.bogo);
>    delete my.p;
>    print('my.p=',my.p);
> }
> print('my.p=',my.p);
> print
> ('PathFinder.plugins=',PathFinder.plugins,PathFinder.plugins.bogo);
> print("Bye!");
>
>
> The output is:
>
> step...@jareth:~/cvs/fossil/v8-addons/addons$ m && ./shell js/pf.js
> make: Nothing to be done for `default'.
> PathFinder-js.cc:43 : Wrapped PathFinder @0xb7c940a0 in a
> Persistent<Object>.
> PathFinder-js.cc:69 : PathFinder([/usr/bin0/bin0~/bin], [], [0])
> PathFinder-js.cc:43 : Wrapped PathFinder @0x88cda78 in a
> Persistent<Object>.
> PathFinder-js.cc:69 : PathFinder([/usr/bin1/bin1~/bin], [], [1])
> PathFinder-js.cc:43 : Wrapped PathFinder @0x88cda40 in a
> Persistent<Object>.
> PathFinder-js.cc:69 : PathFinder([/usr/bin2/bin2~/bin], [], [2])
> PathFinder-js.cc:43 : Wrapped PathFinder @0x88cdc10 in a
> Persistent<Object>.
> PathFinder-js.cc:69 : PathFinder([/usr/bin3/bin3~/bin], [], [3])
> PathFinder-js.cc:43 : Wrapped PathFinder @0x88cdd00 in a
> Persistent<Object>.
> PathFinder-js.cc:69 : PathFinder([/usr/bin4/bin4~/bin], [], [4])
> PathFinder-js.cc:43 : Wrapped PathFinder @0x88cddf0 in a
> Persistent<Object>.
> my.p= [object Object] object bogo was here
> my.p= undefined
> my.p= undefined
> PathFinder.plugins= [object Object] bogo was here
> Bye!
> ---------------------------------------
> (end demo)
>
>
> :-?
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to