I can't yet demonstrate that the C++ object is deleted. I wrote a simple loop
in JS
function f()
{
for (i = 0; i < 1000; ++i)
{
new jfx.ByteBuffer();
}
}
and run v8 with the flags
--log_handles --gc_interval=10 --trace_gc --gc_global
I get debugging messages
constructed byte buffer 0x8a1e0e8, isWeak = 1
0x8a1e0e8: isWeak=1, isNearDeath=0
Mark-sweep 0.4 -> 0.4 MB, 20 ms.
constructed byte buffer 0x8a440f8, isWeak = 1
0x8a1e0e8: isWeak=1, isNearDeath=0
The weak pointers are never marked as NearDeath.
From v8.log I get
GlobalHandle::MakeWeak,0x8a538b4
GlobalHandle::MakeWeak,0x8a538b4
markcompact,begin,2,797574,1224457984667
markcompact,end,2,809572,1224457984679
scavenge,begin,2,809572,1224457984679
scavenge,end,2,810572,1224457984679
GlobalHandle::MakeWeak,0x8a538b4
so you'd think that if the JS objects were no longer referenced then I would
see them deleted.
So what do I have to do to generate garbage in scripts if the above for-loop
doesn't do it.
--
Anthony Shipman Mamas don't let your babies
a...@iinet.net.au grow up to be outsourced.
static void CollectGarbage (void)
{
syslog (LOG_NOTICE, "collecting garbage");
TryCatch tryCatch;
Local <Context> currentContext (Context::GetCurrent ( ));
Local <Object> global (currentContext->Global ( ));
Local <Value> gc (global->Get (String::New ("gc")));
Local <Function> gcFunc (Function::Cast (*gc));
(void) gcFunc->Call (global, 0, NULL);
syslog (LOG_NOTICE, "collected garbage");
}
I can't make it collect my object even when doing
for (i = 0; i < 1000; ++i)
{
var x = new jfx.ByteBuffer();
x = 0;
gc();
}
and flags
--new_space_size=65536 --old_space_size=2500000 --expose_gc --log_handles --trace_gc --gc_global
Ignore this. I've got it going.
At one point I was getting a segmentation violation because I wrote
wrap->jsObject_ = Persistent<Object>(args.This());
instead of
wrap->jsObject_ = Persistent<Object>::New(args.This());
I wonder what the use of the first constructor is?
I've also got dumb syntax error messages e.g. writing
for (int i = 0; i < 10; ++i)
{
}
gives me
-------------
<unknown>:146: Uncaught SyntaxError: Unexpected identifier
#
# Fatal error in src/handles-inl.h, line 45
# CHECK(location_ != __null) failed
#
Aborted
-------------
where 146 is not a valid line number.
I've got it going.
At one point I was getting a segmentation violation because I wrote
wrap->jsObject_ = Persistent<Object>(args.This());
instead of
wrap->jsObject_ = Persistent<Object>::New(args.This());
I wonder what the use of the first constructor is?
At one point I was getting a segmentation violation because I wrote
wrap->jsObject_ = Persistent<Object>(args.This());
instead of
wrap->jsObject_ = Persistent<Object>::New(args.This());
I wonder what the use of the first constructor is?I, too, have wondered this.
Persistent handles automatically convert to plain Handles so you can do
Persistent<Object> obj = ...;
Handle<Object> hnd = obj;
This means that you may have a Handle value that you know is a
persistent handle. In that case the first constructor can be used to
"cast" the handle back to a persistent handle
Persistent<Object> re_obj = Persistent<Object>(hnd);
Unfortunately the constructor does not verify that the handle being
converted is a persistent handle, otherwise that would have caught the
issue with your code.
-- Christian
We wanted to add this but haven't been able to come up with a good
model for checking whether a handle is persistent or not. All we see
at the point where the cast takes place is a single pointer value and
there is currently no way to know whether that pointer comes from a
handle scope or a persistent handle.
> declare it 'explicit' to make it less likely to be used by accident
It already is.
> add a comment explaining the situation
Yes, I'll do that.