Exposed Class not Garbage Collected

87 views
Skip to first unread message

Corey

unread,
Mar 6, 2011, 8:12:20 PM3/6/11
to v8-u...@googlegroups.com
Hello, I'm working on a game engine that uses V8 JavaScript for scripting, and I'm exposing a Sprite class to the JavaScript API, and I've run into a problem: it isn't being garbage collected.

Here's how I'm wrapping the class:
v8::Persistent<v8::ObjectTemplate> _template;

// ...

v8::Handle<v8::ObjectTemplate> CreateTemplate() { v8::HandleScope handle_scope; v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); // ... set some methods ... v8::Handle<v8::ObjectTemplate> t = templ->InstanceTemplate(); t->SetInternalFieldCount(1); return handle_scope.Close(t); } FUNC_TYPE Wrap(FUNC_ARGS) { v8::HandleScope handle_scope; if (args.IsConstructCall()) { v8::String::Utf8Value filename(args[0]); Video::Sprite* s = new Video::Sprite(Scripting::ToCString(filename)); // Create the class template if it doesn't exist yet if (_template.IsEmpty()) { _template = v8::Persistent<v8::ObjectTemplate>::New(CreateTemplate()); } v8::Persistent<v8::Object> result = v8::Persistent<v8::Object>::New(_template->NewInstance()); result.MakeWeak(s, WeakRefCallback); result->SetInternalField(0, v8::External::New(s)); return handle_scope.Close(result); } return v8::Undefined(); } void WeakRefCallback(v8::Persistent<v8::Value> object, void* parameter) { Video::Sprite* s = static_cast<Video::Sprite*>(parameter); delete s; object.Dispose(); }

I'm testing the garbage collection by continually creating and deleting sprites in the JavaScript. However the WeakRefCallback is never called, and the memory usage continues to rise and rise. I've checked to make sure that the GC is running (with v8::V8::AddGCEpilogueCallback) and it is, quite frequently, however this is not disposing of the deleted JavaScript sprites.

Anyone have any ideas as to why?

Anton Muhin

unread,
Mar 9, 2011, 8:35:41 AM3/9/11
to v8-u...@googlegroups.com, Corey
Corey,

immediately I see nothing suspicious. I think you need to provide the
full (but ideally short) example of the problem. The most appreciate
form would be to modify test/test-api.cc to include the test which
demonstrates the problem.

yours,
anton.

> --
> v8-users mailing list
> v8-u...@googlegroups.com
> http://groups.google.com/group/v8-users

Jeff Hauswirth

unread,
Mar 9, 2011, 4:48:36 PM3/9/11
to v8-u...@googlegroups.com, Corey
I also had this problem.  My first problem was, I was calling MakeWeak on v8::Persistent<v8::ObjectTemplate> (Fixed by calling MakeWeak on v8::Persistent<v8::Object>)
Even after that change I was still not getting the callback. I then added-
  while(!v8::V8::IdleNotification()) {};
I finally started to get the callback so I could clean up my wrapped C++ objects.
I call IdleNotification on app exit to clean up what's still alive so I don't get mem leaks reported.
This may not be the correct way of doing it, but so far it works.
Anton also helped me with one important thing in my WeakReferenceCallback.
"You should either Dispose the persistent handle passed or revive it
(with MakeWeak)."
In my case I just called Dispose on the passed in v8::Persistent<v8::Value>.

Corey

unread,
Mar 13, 2011, 4:21:49 PM3/13/11
to v8-u...@googlegroups.com, Corey
Ah, adding v8::V8::IdleNotification(); at the end of the each game loop fixed it! Thanks a lot!

Corey

unread,
Mar 20, 2011, 11:41:52 PM3/20/11
to v8-u...@googlegroups.com, Corey
Hm, after awhile (in some situations) v8::V8::IdleNotification() seems to cause very noticeable lag spikes. However, I have yet to find a way to get V8's Garbage Collector to clean up after my wrapped C++ objects. Does anyone have any suggestions?
Reply all
Reply to author
Forward
0 new messages