Hi Oliver, thanks for the response.
I looked at the JavascriptContext.Collect method and it consists of this one line:
while(!v8::V8::IdleNotification()) {};
Part of the comments for IdleNotification are:
That seems like a reasonable guarantee that V8 has cleaned up all the objects it can.
Also as I've been looking through the code I noticed that the JavascriptExternal class maintains this member variable:
System::Runtime::InteropServices::GCHandle mObjectHandle;
I assume that is as good as a strong reference in C#.
As I look in JavascriptContext I find that it has this member variable:
vector<JavascriptExternal*>* mExternals;
And it only deletes the JavascriptExternal objects upon JavascriptContext destruction.
Based on that alone I'd think it is possible that V8 is cleaning up it's objects but the underlying JavascriptExternal objects never get cleaned up until the context is disposed, which in turn stops C# objects from getting collected due to the GCHandle held by the JavascriptExternal objects.
Also the following url indicates that we should be maintaining V8 weak handles that provide us with callbacks to know when it cleans up an object so we can properly dispose of the underlying External object:
http://create.tpsitulsa.com/wiki/V8/Persistent_Handles
There are no places in the noesis source code where MakeWeak() is called which makes me really think this could be the missing piece.
I've noticed you often respond to questions about noesis.javascript.net.
What is your relation to the project if you don't mind me asking?
I'm going to see if I can implement the V8 weak references stuff, but neither C++ CLI or native C++ are my strong points.
If there's an active maintainer I'd love to work with them to solve the problem.
Thanks for your help.
Ian Reed
I looked at the JavascriptContext.Collect method and it consists of this one line:
while(!v8::V8::IdleNotification()) {};
Part of the comments for IdleNotification are:
- Optional notification that the embedder is idle.
- V8 uses the notification to reduce memory footprint.
- This call can be used repeatedly if the embedder remains idle.
- Returns true if the embedder should stop calling IdleNotification
- until real work has been done. This indicates that V8 has done
-
as much cleanup as it will be able to do.
That seems like a reasonable guarantee that V8 has cleaned up all the objects it can.
Also as I've been looking through the code I noticed that the JavascriptExternal class maintains this member variable:
System::Runtime::InteropServices::GCHandle mObjectHandle;
I assume that is as good as a strong reference in C#.
As I look in JavascriptContext I find that it has this member variable:
vector<JavascriptExternal*>* mExternals;
And it only deletes the JavascriptExternal objects upon JavascriptContext destruction.
Based on that alone I'd think it is possible that V8 is cleaning up it's objects but the underlying JavascriptExternal objects never get cleaned up until the context is disposed, which in turn stops C# objects from getting collected due to the GCHandle held by the JavascriptExternal objects.
Also the following url indicates that we should be maintaining V8 weak handles that provide us with callbacks to know when it cleans up an object so we can properly dispose of the underlying External object:
http://create.tpsitulsa.com/wiki/V8/Persistent_Handles
There are no places in the noesis source code where MakeWeak() is called which makes me really think this could be the missing piece.
I've noticed you often respond to questions about noesis.javascript.net.
What is your relation to the project if you don't mind me asking?
I'm going to see if I can implement the V8 weak references stuff, but neither C++ CLI or native C++ are my strong points.
If there's an active maintainer I'd love to work with them to solve the problem.
Thanks for your help.
Ian Reed