Thank you! Great help here. Amazing folks!
On Nov 17, 2017 6:21 PM, "J Decker" <d3c...@gmail.com> wrote: > > > On Fri, Nov 17, 2017 at 7:25 AM, Jean-Marc Le Roux < > jeanmarc.ler...@aerys.in> wrote: > >> My assumption is that my test app terminates before the GC has a chance >> to run. >> To test this: >> >> - I run node with the --expose-gc option >> - I call global.gc() at the end of my test app >> >> In this case, the destructor of my ObjectWrap is indeed called. >> >> *So it seams the GC doesn't simply "collect everything" when the app >> terminates.* >> *Why is that?* >> >> It sounds like a pretty bad things to do: some behaviors might expect the >> destructor to be called in order to close a socket, etc... >> > > because all memory is released. when the app exits. Why do extra work of > minor side effects? > but ya, if tf you were returning like a file to a handle and expected the > close in order to flush all data out to a device it's bad... > > You can attach to Node::AtExit( ... ) > https://nodejs.org/api/addons.html#addons_atexit_hooks > > which should be called so you an finalize such things. > > but sockets get closed by the system when a application exits also. and > files are closed.... > > > >> >> On Friday, November 17, 2017 at 10:27:22 AM UTC+1, Jean-Marc Le Roux >> wrote: >>> >>> Thanks for the great help! >>> I think it makes a lot of sense now. >>> >>> So I've extended ObjectWrap like so: >>> >>> class BSONObject : public node::ObjectWrap >>>> { >>>> private: >>>> bson_t* _bson; >>>> public: >>>> BSONObject(bson_t* bson, Local<ObjectTemplate> tpl) : >>>> _bson(bson) >>>> { >>>> Local<Object> obj = tpl->NewInstance(); >>>> initialize(v8::Isolate::GetCurrent(), obj, bson); >>>> Wrap(obj); >>>> } >>> >>> >>> >>> ~BSONObject() >>>> { >>>> std::cout << "~BSONObject()" << std::endl; >>>> bson_destroy(_bson); >>>> } >>> >>> >>> >>> static >>>> Local<ObjectTemplate> >>>> create_template(Isolate* isolate, const bson_t* document) >>>> { >>>> Local<ObjectTemplate> tpl = ObjectTemplate::New(isolate); >>>> tpl->SetInternalFieldCount(1); >>> >>> >>> And the "insert" function that I expose in JS and that instanciates the >>> BSONObject is written like this: >>> >>> void >>>> insert(const FunctionCallbackInfo<Value>& args) >>>> { >>>> Isolate* isolate = args.GetIsolate(); >>>> >>>> db->insert( >>>> json_stringify(isolate, args[0]), >>>> [&args, isolate](const bson_t* document) >>>> { >>>> if (!args[1]->IsUndefined()) >>>> { >>>> Local<Function> callback = >>>> Local<Function>::Cast(args[1]); >>>> Local<Object> obj = Object::New(isolate); >>>> *Local<Value> argv[] = { (new >>>> BSONObject(bson_copy(document)))->handle(isolate) };* >>>> callback->Call(isolate->GetCurrentContext()->Global(), >>>> 1, argv); >>>> } >>>> } >>>> ); >>>> } >>> >>> >>> It runs fine. >>> But the destructor is never called (I never see "~BSONObject()" on >>> stdout). >>> >>> Did I miss something? >>> >>> Thanks ! >>> >>> 2017-11-16 22:01 GMT+01:00 J Decker <d3c...@gmail.com>: >>> >>>> You don't manage the instance, the v8 engine does. When it's no longer >>>> referenced in the engine, it's garbage collected which triggers the >>>> callback set when the perisstent object is made weak. >>>> >>>> You don't need to keep it anywhere, the object returned into the engine >>>> has Internal Fields ( SetInternalFieldCount(1) ) which is used to point to >>>> your native class instance. So when the callback is called, it knows what >>>> to call to destruct it. >>>> >>>> You have to 'keep it' in the javascript scrpit if you want to keep it, >>>> it's not 'kept' in the native code... >>>> >>>> >>>> --- This is some code I've done that uses setweak directly; but it's >>>> fairly scattered.... >>>> >>>> https://github.com/d3x0r/sack.vfs/blob/master/src/jsonParse.cc#L18 >>>> >>>> You can create an instance of your wrapped object with >>>> >>>> Local<Function> cons = Local<Function>::New( isolate, constructor ); >>>> cons->NewInstance( isolate->GetCurrentContext(), argc, argv >>>> ).ToLocalChecked() ; >>>> >>>> Hmm that's not the best example source... >>>> >>>> https://github.com/d3x0r/sack.vfs/blob/master/src/vfs_module.cc#L407 >>>> >>>> This creates a buffer, and makes it weak... >>>> https://github.com/d3x0r/sack.vfs/blob/master/src/vfs_module.cc#L438 >>>> >>>> Local<Object> arrayBuffer = ArrayBuffer::New( isolate, buf, len ); >>>> PARRAY_BUFFER_HOLDER holder = GetHolder(); >>>> holder->o.Reset( isolate, arrayBuffer ); >>>> holder->o.SetWeak<ARRAY_BUFFER_HOLDER>( holder, releaseBuffer, >>>> WeakCallbackType::kParameter ); >>>> holder->buffer = buf; >>>> >>>> PARRAY_BUFFER_HOLDER is just a type that holds the thing to be free (or >>>> object containing things to be released), and the persistent reference that >>>> has been made weak... >>>> >>>> struct arrayBufferHolder { >>>> void *buffer; >>>> Persistent<Object> o; >>>> }; >>>> >>>> >>>> >>>> On Thu, Nov 16, 2017 at 9:56 AM, Jean-Marc Le Roux < >>>> jeanmarc.ler...@aerys.in> wrote: >>>> >>>>> Node offers a C++ Clss extention ObjectWrap >>>>> >>>>> >>>>> Thanks ! >>>>> It is related to node. Yet I'm not sure how I'm supposed to use >>>>> ObjectWrap. >>>>> >>>>> I understand I have to create my own class that extends ObjectWrap and >>>>> implement a proper destructor. >>>>> Then I'll instanciate that class to wrap my Local<Object>. But how do >>>>> I manage such instance? >>>>> If I don't keep it somewhere, it will be destructed. >>>>> If I keep it around, then I'm keeping references to potentially >>>>> deallocated memory. >>>>> >>>>> It feels like I end up with the same problem... >>>>> >>>>> 2017-11-16 18:36 GMT+01:00 J Decker <d3c...@gmail.com>: >>>>> >>>>>> >>>>>> >>>>>> On Thu, Nov 16, 2017 at 1:24 AM, Jean-Marc Le Roux < >>>>>> jeanmarc.ler...@aerys.in> wrote: >>>>>> >>>>>>> I assume you're storing references to the objects as Persistent? >>>>>>> >>>>>>> >>>>>>> Nope. You've got the whole code up there. >>>>>>> So if I understand correctly: >>>>>>> >>>>>>> - the objects I need to keep track of the lifecycle should be >>>>>>> made Persistent ; >>>>>>> - all the other values can be set as Local ; >>>>>>> - I should set the weak callback using MakeWeak ; >>>>>>> - callback will be called when such object is GCed and I can >>>>>>> free my C/C++ memory then. >>>>>>> >>>>>>> Is that correct ? >>>>>>> >>>>>> >>>>>> Yes. I sthis perhaps related to Node? >>>>>> Node offers a C++ Clss extention ObjectWrap >>>>>> >>>>>> https://nodejs.org/api/addons.html#addons_wrapping_c_objects >>>>>> https://github.com/nodejs/node/blob/master/src/node_object_wrap.h >>>>>> >>>>>> which simplifies that whole process... when the object is GC'd the >>>>>> class destructor will get called so you can release values there. >>>>>> >>>>>> >>>>>> >>>>>>> >>>>>>> 2017-11-15 19:50 GMT+01:00 J Decker <d3c...@gmail.com>: >>>>>>> >>>>>>>> I assume you're storing references to the objects as Persistent? >>>>>>>> All you need to do then is call SetWeak() https://v8docs.nodes >>>>>>>> ource.com/node-0.10/d2/d78/classv8_1_1_persistent.html >>>>>>>> void MakeWeak (void *parameters, WeakReferenceCallback callback) >>>>>>>> >>>>>>>> the callback is called when the object is GC'd. >>>>>>>> >>>>>>>> >>>>>>>> On Wed, Nov 15, 2017 at 8:37 AM, Jean-Marc Le Roux < >>>>>>>> jeanmarc.ler...@aerys.in> wrote: >>>>>>>> >>>>>>>>> So I've found a solution to make things lazy: I set an accessor >>>>>>>>> instead of decoding/setting the actual value. >>>>>>>>> >>>>>>>>> void >>>>>>>>> getter(Local<Name> property, const PropertyCallbackInfo<Value>& >>>>>>>>> info) >>>>>>>>> { >>>>>>>>> Isolate* isolate = info.GetIsolate(); >>>>>>>>> >>>>>>>>> const bson_t* document = reinterpret_cast<bson_t*>( >>>>>>>>> info.This() >>>>>>>>> ->Get(String::NewFromUtf8(isolate, >>>>>>>>> "__bson_document_ptr")) >>>>>>>>> ->ToInt32()->Value() >>>>>>>>> ); >>>>>>>>> >>>>>>>>> char key[255]; >>>>>>>>> property->ToString(isolate)->WriteUtf8(key, 255); >>>>>>>>> >>>>>>>>> bson_iter_t iter; >>>>>>>>> bson_iter_init(&iter, document); >>>>>>>>> // FIXME: index the property so we don't have to find it >>>>>>>>> bson_iter_find(&iter, key); >>>>>>>>> >>>>>>>>> // FIXME: replace the accessor with the deserialized value >>>>>>>>> >>>>>>>>> info.GetReturnValue().Set(iterator_to_value(isolate, &iter)); >>>>>>>>> } >>>>>>>>> >>>>>>>>> Local<Value> >>>>>>>>> fill_object(Isolate* isolate, Local<Object>& obj, const bson_t* >>>>>>>>> document) >>>>>>>>> { >>>>>>>>> obj->Set( >>>>>>>>> String::NewFromUtf8(isolate, "__bson_document_ptr"), >>>>>>>>> Int32::New(isolate, reinterpret_cast<intptr_t>(document)) >>>>>>>>> ); >>>>>>>>> >>>>>>>>> bson_iter_t iter; >>>>>>>>> if (bson_iter_init(&iter, document)) >>>>>>>>> { >>>>>>>>> while (bson_iter_next(&iter)) >>>>>>>>> { >>>>>>>>> const char* key = bson_iter_key(&iter); >>>>>>>>> >>>>>>>>> if (!obj->Has(String::NewFromUtf8(isolate, >>>>>>>>> key))) >>>>>>>>> { >>>>>>>>> obj->SetAccessor( >>>>>>>>> isolate->GetCurrentContext(), >>>>>>>>> String::NewFromUtf8(isolate, key), >>>>>>>>> &getter >>>>>>>>> ); >>>>>>>>> } >>>>>>>>> } >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> The secret sauce is to : >>>>>>>>> >>>>>>>>> - keep the original data (the bson_t) allocated >>>>>>>>> - store the corresponding pointer in a v8::Object >>>>>>>>> >>>>>>>>> But now I have a memory leak because those pointers will never be >>>>>>>>> freed. >>>>>>>>> How can I know when the Object will be disposed by the GC? >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> >>>>>>>>> -- >>>>>>>>> -- >>>>>>>>> v8-users mailing list >>>>>>>>> v8-users@googlegroups.com >>>>>>>>> http://groups.google.com/group/v8-users >>>>>>>>> --- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "v8-users" group. >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an email to v8-users+unsubscr...@googlegroups.com. >>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> -- >>>>>>>> v8-users mailing list >>>>>>>> v8-users@googlegroups.com >>>>>>>> http://groups.google.com/group/v8-users >>>>>>>> --- >>>>>>>> You received this message because you are subscribed to a topic in >>>>>>>> the Google Groups "v8-users" group. >>>>>>>> To unsubscribe from this topic, visit >>>>>>>> https://groups.google.com/d/topic/v8-users/aVeevQcHJ2c/unsubscribe. >>>>>>>> To unsubscribe from this group and all its topics, send an email to >>>>>>>> v8-users+unsubscr...@googlegroups.com. >>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Jean-Marc Le Roux* >>>>>>> >>>>>>> >>>>>>> Founder and CEO of Aerys (http://aerys.in) >>>>>>> >>>>>>> Blog: http://blogs.aerys.in/jeanmarc-leroux >>>>>>> Cell: (+33)6 20 56 45 78 >>>>>>> Phone: (+33)9 72 40 17 58 >>>>>>> >>>>>>> -- >>>>>>> -- >>>>>>> v8-users mailing list >>>>>>> v8-users@googlegroups.com >>>>>>> http://groups.google.com/group/v8-users >>>>>>> --- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "v8-users" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>> send an email to v8-users+unsubscr...@googlegroups.com. >>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>> >>>>>> >>>>>> -- >>>>>> -- >>>>>> v8-users mailing list >>>>>> v8-users@googlegroups.com >>>>>> http://groups.google.com/group/v8-users >>>>>> --- >>>>>> You received this message because you are subscribed to a topic in >>>>>> the Google Groups "v8-users" group. >>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/to >>>>>> pic/v8-users/aVeevQcHJ2c/unsubscribe. >>>>>> To unsubscribe from this group and all its topics, send an email to >>>>>> v8-users+unsubscr...@googlegroups.com. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> *Jean-Marc Le Roux* >>>>> >>>>> >>>>> Founder and CEO of Aerys (http://aerys.in) >>>>> >>>>> Blog: http://blogs.aerys.in/jeanmarc-leroux >>>>> Cell: (+33)6 20 56 45 78 >>>>> Phone: (+33)9 72 40 17 58 >>>>> >>>>> -- >>>>> -- >>>>> v8-users mailing list >>>>> v8-users@googlegroups.com >>>>> http://groups.google.com/group/v8-users >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "v8-users" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to v8-users+unsubscr...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>>> -- >>>> v8-users mailing list >>>> v8-users@googlegroups.com >>>> http://groups.google.com/group/v8-users >>>> --- >>>> You received this message because you are subscribed to a topic in the >>>> Google Groups "v8-users" group. >>>> To unsubscribe from this topic, visit https://groups.google.com/d/to >>>> pic/v8-users/aVeevQcHJ2c/unsubscribe. >>>> To unsubscribe from this group and all its topics, send an email to >>>> v8-users+unsubscr...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> >>> >>> -- >>> *Jean-Marc Le Roux* >>> >>> >>> Founder and CEO of Aerys (http://aerys.in) >>> >>> Blog: http://blogs.aerys.in/jeanmarc-leroux >>> Cell: (+33)6 20 56 45 78 <+33%206%2020%2056%2045%2078> >>> Phone: (+33)9 72 40 17 58 <+33%209%2072%2040%2017%2058> >>> >> -- >> -- >> v8-users mailing list >> v8-users@googlegroups.com >> http://groups.google.com/group/v8-users >> --- >> You received this message because you are subscribed to the Google Groups >> "v8-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to v8-users+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > -- > v8-users mailing list > v8-users@googlegroups.com > http://groups.google.com/group/v8-users > --- > You received this message because you are subscribed to a topic in the > Google Groups "v8-users" group. > To unsubscribe from this topic, visit https://groups.google.com/d/ > topic/v8-users/aVeevQcHJ2c/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > v8-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.