Re: [v8-users] Storing a weak reference to a function, or otherwise avoiding a memory leak
On Sat, Sep 16, 2017 at 3:17 AM, Zach Bjornson wrote: > Hello, > > I'm trying to implement this type of interface: > > var myObj = new MyObj(); > myObj.onevent = function () { > // might be a reference to myObj here > } > myObj.doSomethingAsync(); // causes `onevent` to fire; can be called more > than once > > `onevent` (a C++ setter) currently stores the callback function in a > Persistent. However, if the callback has a reference to `myObj`, > then `myObj` will never be GC'ed. > > What's the correct way to implement this? > > I thought of (1) storing a weak reference to the function when it's set, (b) > creating a Persistent handle to the function when `doSomethingAsync()` is > called, (c) resetting that Persistent when the event is fired. However, I'm > not sure how to store a weak reference to the function in the first place. > > Thanks, > Zach `myObj.onevent()` invokes `onevent()` with `this === myObj`. Unless you want to deviate significantly from normal JS semantics, you would need to maintain a reference to `myObj` anyway. In other words, don't worry about it! -- -- 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.
Re: [v8-users] Storing a weak reference to a function, or otherwise avoiding a memory leak
> > `myObj.onevent()` invokes `onevent()` with `this === myObj`. Unless > you want to deviate significantly from normal JS semantics, you would > need to maintain a reference to `myObj` anyway. > (The spec I'm emulating actually states that `onevent()` is invoked with the global context.) Sorry, I don't think I described the issue well. The issue is not `onevent` needing to maintain a contextual ref to `myObj`, but rather that if `onevent` references `myObj` in its JS function body, then `myObj` will not get GC'ed because `onevent`'s function is stored in a Persistent handle. JS: var myObj = new MyObj(); myObj.onevent = function () { // (a C++ setter) console.log(myObj); // reference to myObj here } myObj.doSomethingAsync(); // causes `onevent` to fire eventually C++ (pseudo) class MyObj : ObjectWrap { Persistent _onevent; void setOnEvent(Local prop, const PropertyCallbackInfo& info); // stores fn arg in _onevent } A work-around is to not use C++ for the `onevent` setter, but I'm still curious how this would be done in C++. Would the class member be instead a Local, and have to be set with `EscapeableHandleScope scope(isolate); _onevent = scope.Escape(functionArg);` (ish)? Thanks, Zach -- -- 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.
Re: [v8-users] Storing a weak reference to a function, or otherwise avoiding a memory leak
On Mon, Sep 18, 2017 at 6:13 PM, Zach Bjornson wrote: >> `myObj.onevent()` invokes `onevent()` with `this === myObj`. Unless >> you want to deviate significantly from normal JS semantics, you would >> need to maintain a reference to `myObj` anyway. > > > (The spec I'm emulating actually states that `onevent()` is invoked with the > global context.) Sorry, I don't think I described the issue well. > > The issue is not `onevent` needing to maintain a contextual ref to `myObj`, > but rather that if `onevent` references `myObj` in its JS function body, > then `myObj` will not get GC'ed because `onevent`'s function is stored in a > Persistent handle. > > JS: > > var myObj = new MyObj(); > myObj.onevent = function () { // (a C++ setter) > console.log(myObj); // reference to myObj here > } > myObj.doSomethingAsync(); // causes `onevent` to fire eventually > > C++ (pseudo) > > class MyObj : ObjectWrap { > Persistent _onevent; > void setOnEvent(Local prop, const PropertyCallbackInfo& > info); // stores fn arg in _onevent > } > > A work-around is to not use C++ for the `onevent` setter, but I'm still > curious how this would be done in C++. Would the class member be instead a > Local, and have to be set with `EscapeableHandleScope > scope(isolate); _onevent = scope.Escape(functionArg);` (ish)? > > Thanks, > Zach myObj.onevent is always going to be a strong reference but what you can do is make myObj strong when myObj.doSomethingAsync() is called, and weak again when myObj.onevent() is invoked. Once it's weak again (or when you reset the persistent handle), the myObj.onevent -> myObj cycle no longer matters, the object will be eligible for reclamation. -- -- 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.