How to use v8::Persistent::SetWeak to avoid memory leak

2,878 views
Skip to first unread message

Yorath Wang

unread,
Oct 23, 2013, 11:25:10 PM10/23/13
to v8-u...@googlegroups.com
I am using v8 (tag 3.22.19) built as shared library, the environment is windows 8.1 x64, visual studio 2010.
I use External::new(ptr)  to pass the pointer to Print function, but the ptr is allocated use new, I don't know how to free the memory.
Then i came across the API SetWeak, but there is no document at all. I try to use it with the codes below, but the WeakPtrCallback is never called, which leads to the memory leak.
Anyone knows how to deal with this problem? Thanks!

#include <v8.h>
#include <vld.h>
#include <memory>

void Print(const v8::FunctionCallbackInfo<v8::Value>& data) {

}

void WeakPtrCallback(
    const v8::WeakCallbackData<v8::Object, std::weak_ptr<int>>& data) {
  delete data.GetParameter();
}

int main() {
  auto isolate = v8::Isolate::GetCurrent();
  v8::HandleScope handle_scope(isolate);
  auto context = v8::Context::New(isolate);

  auto ptr = std::shared_ptr<int>(new int(3));
  auto data = new std::weak_ptr<int>(ptr);

  auto global = context->Global();
  auto func_tpl = v8::FunctionTemplate::New(Print, v8::External::New(data));

  context->Enter();

  auto func = func_tpl->GetFunction();
  global->Set(v8::String::New("print"), func);
  auto obj = v8::Persistent<v8::Object>(isolate, global);
  obj.SetWeak<std::weak_ptr<int>>(data, WeakPtrCallback);

  context->Exit();
  obj.Reset();

  return 0;
}

Ben Noordhuis

unread,
Oct 24, 2013, 4:41:53 AM10/24/13
to v8-u...@googlegroups.com
Your callback runs at some undefined time in the future when the
garbage collector has determined that there are no more references to
the weak object. If your program is short-lived, it may never run.

Of course, if you call v8::Persistent<T>::Reset(), it never runs
because you've zapped the persistent storage cell.

Yorath Wang

unread,
Oct 24, 2013, 5:00:58 AM10/24/13
to v8-u...@googlegroups.com
Thanks for your reply.
I use while (!v8::V8::IdleNotification()) {} force gc to release the memory, but that callback is not called either.
Could you please show me a right way to use SetWeak to avoid memroy leak? Thanks




--
--
v8-users mailing list
v8-u...@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/FdfYWPWgX9k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to v8-users+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Sven Panne

unread,
Oct 24, 2013, 5:20:07 AM10/24/13
to v8-u...@googlegroups.com
On Thu, Oct 24, 2013 at 11:00 AM, Yorath Wang <yorat...@gmail.com> wrote:
Thanks for your reply.
I use while (!v8::V8::IdleNotification()) {} force gc to release the memory, but that callback is not called either.
Could you please show me a right way to use SetWeak to avoid memroy leak? Thanks

To shorten this discussion a bit: Using weak callbacks (a.k.a. finalizers) will never give you any guarantees if/when they are called, it is just based on best-effort. If you really need timely destruction, you will need some form of explicit API for the kind of objects you are working with.

Andreas Rossberg

unread,
Oct 24, 2013, 5:46:23 AM10/24/13
to v8-u...@googlegroups.com
Right, and just to be clear: that is true for just about any
finalisation mechanism. Since this is such a frequent question, let me
reiterate two fundamental wisdoms regarding GC:

1. Forcing GC explicitly almost always trades bad behaviour for worse behaviour.
2. Finalisation almost always is the wrong solution to the wrong problem.

And once you start violating the former just to work around the
consequences of violating the latter, you are definitely in the
non-exceptional case of either. ;)

/Andreas

Yorath Wang

unread,
Oct 24, 2013, 10:36:52 AM10/24/13
to v8-u...@googlegroups.com
Thanks a lot. But are there any ways to avoid the memory leak?


Murat Gözcü

unread,
Apr 1, 2014, 11:52:42 AM4/1/14
to v8-u...@googlegroups.com, yorat...@gmail.com
sorry for my missed english.

this is "indirect" response to your question.

you can set to null objects at "script side", to make garbage collected.



24 Ekim 2013 Perşembe 06:25:10 UTC+3 tarihinde Yorath Wang yazdı:

Jane Chen

unread,
Apr 1, 2014, 6:53:04 PM4/1/14
to v8-u...@googlegroups.com, yorat...@gmail.com
Does that trigger GC?

I also learned that there's Isolate::RequestGarbageCollectionForTesting now.  Hope that'll do it, although I haven't tried it yet.

Murat Gözcü

unread,
Apr 3, 2014, 10:01:33 AM4/3/14
to v8-u...@googlegroups.com, yorat...@gmail.com
yes.

but there has some tricks "i experienced".

my observations:

when you call "while(!V8::IdleNotification()) {};" after script run, WeakPointerCallbacks called successfully, 

but after first IdleNotification() loop, weakcallbacks not triggered. 

i dont know why ?.

simply:
first IdleNotification() loop triggers callbacks, but second and more not.


2 Nisan 2014 Çarşamba 01:53:04 UTC+3 tarihinde Jane Chen yazdı:

Alex Chi

unread,
Apr 6, 2014, 11:47:47 PM4/6/14
to v8-u...@googlegroups.com, yorat...@gmail.com
In recently, I am coding a script wrapper by Google V8. You can reference the sample(tut03_cls). I use the WeakCallback to free the memory that was allocated by c++.

Three Important Things:
  1. Call `data.GetValue().Clear();` in the WeakCallback.
  2. Set the object to `null` in javascript file.
  3. Call `while(!v8::V8::IdleNotification()) {};` after run script.
Hope these can help you.


在 2013年10月24日星期四UTC+8下午10时36分52秒,Yorath Wang写道:

Jane Chen

unread,
Apr 8, 2014, 6:28:19 PM4/8/14
to v8-u...@googlegroups.com, yorat...@gmail.com
Does garbage collection happen in the same thread in which idleNotification() is called?  Can garbage collection of an Isolate happens in a separate thread when this thread is still in the Isolate?
Reply all
Reply to author
Forward
0 new messages