Jake
Normally there is no reason to do any cleanup on process termination,
since all file handles and network connections etc. are automatically
terminated by the file system. All the resources, including memory, of
a process are forcibly released when a process exits, so it's unlikely
that the GC even runs at that time.
If you need to explicitly release a custom resource, you should look
at defining an atexit callback in C++.
Garbage is only collected when new-space is full, so if you allocate
few but extremely big objects you may run out of memory before
new-space has been filled. That could be the explanation for bad
behavior when really big objects are involved.
-- Christian
If it is important to clean some or all of your objects up then you
could keep a reference to all the current live objects in your own
code. That way you could dispose of them properly yourself exactly
when you need it. It depends on your application whether that is an
appropriate approach, but that's one way to do it.
Yes. The garbage collector intentionally does not dispose the
persistent handle, you have to do that yourself. It also does not
collect the javascript object, since it is being kept alive by the
handle. The reason for this is that it gives you the option to keep
the object alive after you get the callback, which is necessary under
some circumstances. Only if you dispose the handle, and there are no
more persistent handles to the object, does it actually get collected.
The Point_Destroy function will be called by the garbage collector when there
are no more references to the object.
- Simon
2008/9/29 bell <marku...@gmail.com>:
CHANGES:
Call the ClearWeak method of the Persistant object in Point_Destroy. This is
done in the v8 tests, so I'll assume they know what they are doing ;-)
Added a getLength method to Point, to demonstrate how methods can be
added/wrapped
Pass the C++ object as parameter to the MakeWeak method for use in
Point_Destroy, as mentioned in the group, and is also done in the v8 tests..
Delete the C++ object via the parameter to MakeWeak,rather than retrieving
the object from the internal field, as mention in the group, and is also
done in the v8 tests..
Added a global counter thats incremented/decremented when object is
created/destroyed. Will almost certainly show uncollected objects at
exit...
You can find latest here: http://home.cfl.rr.com/filedump/v8test.zip
What problems did you encounter exactly?
What problems did you encounter exactly? I plan to update my original
example code to reflect all the information gathered in this
discussion, so people can have a solid example to work from.
Ben
--
Regards,
Ben Nolan
skype: bennolan
cell: +64 21 770 662
Might be a nice reference for someone.
Ben
#include <v8.h>
#include <Ogre.h>
#define V8CALLBACK(type, name)\
v8::Handle<v8::Value> type ## _ ## name(const v8::Arguments& args)
#define V8_GETTER(type, property) \
v8::Handle<v8::Value> type ## _get ##
property(v8::Local<v8::String> property, const v8::AccessorInfo& args)
#define V8_SETTER(type, property) \
void type ## _set ## property(v8::Local<v8::String> property,
v8::Local<v8::Value> value, const v8::AccessorInfo& args)
#define V8INTERNAL(type)\
(static_cast<type>(v8::Local<v8::External>::Cast(args.Holder()-
>GetInternalField(0))->Value()))
#define V8ARGUMENT(type, index)\
(static_cast<type>(v8::Local<v8::External>::Cast(args[index]-
>ToObject()->GetInternalField(0))->Value()))
#define V8ARGUMENTTYPE(type, index)\
( \
args[index]->IsObject() \
&& (args[index]->ToObject()->InternalFieldCount()==2) \
&& (*v8::String::Utf8Value(args[index]->ToObject()-
>GetInternalField(1)->ToString())==std::string(type)) \
)
namespace JSVector{
v8::Handle<v8::ObjectTemplate> instance_template;
v8::Handle<v8::FunctionTemplate> function_template;
V8CALLBACK(Vector,getDistance){
if (!V8ARGUMENTTYPE("Vector", 0))
return ThrowException(v8::String::New("Invalid argument"));
return v8::Number::New(V8INTERNAL(Ogre::Vector3*)-
>distance(*V8ARGUMENT(Ogre::Vector3*, 0)));
}
V8CALLBACK(Vector,getLength){
return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->length());
}
V8CALLBACK(Vector,getNormalized){
return JSVector::New(V8INTERNAL(Ogre::Vector3*)->normalisedCopy());
}
V8_GETTER(Vector,x){
return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->x);
}
V8_SETTER(Vector,x){
V8INTERNAL(Ogre::Vector3*)->x = value->NumberValue();
}
V8_GETTER(Vector,y){
return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->y);
}
V8_SETTER(Vector,y){
V8INTERNAL(Ogre::Vector3*)->y = value->NumberValue();
}
V8_GETTER(Vector,z){
return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->z);
}
V8_SETTER(Vector,z){
V8INTERNAL(Ogre::Vector3*)->z = value->NumberValue();
}
/* Sets internal fields with our idiom of storing the class name in
the second field */
void setInternalFields(v8::Persistent<v8::Object> p, Ogre::Vector3
v){
p->SetInternalField(0, v8::External::New(new
Ogre::Vector3(v.ptr())));
p->SetInternalField(1, v8::String::New("Vector"));
}
/* Construct a new vector */
V8CALLBACK(Vector,create){
if (!args.IsConstructCall())
return ThrowException(v8::String::New("Cannot call constructor
as function"));
v8::Persistent<v8::Object> self =
v8::Persistent<v8::Object>::New(args.Holder());
setInternalFields(self, Ogre::Vector3::ZERO);
return self;
}
/* Only called from c++ */
v8::Handle<v8::Value> New(Ogre::Vector3 v){
v8::Persistent<v8::Object> instance =
v8::Persistent<v8::Object>::New(function_template->GetFunction()-
>NewInstance());
setInternalFields(instance, v);
return instance;
}
/* Create the function and instance templates and register the
Vector constructor */
void Initialize(v8::Handle<v8::ObjectTemplate> global){
// Function Template
function_template = v8::FunctionTemplate::New(Vector_create);
function_template->SetClassName(v8::String::New("Vector"));
// Instance template
instance_template = function_template->InstanceTemplate();
instance_template->SetInternalFieldCount(2);
instance_template->SetAccessor(v8::String::New("x"), Vector_getx,
Vector_setx);
instance_template->SetAccessor(v8::String::New("y"), Vector_gety,
Vector_sety);
instance_template->SetAccessor(v8::String::New("z"), Vector_getz,
Vector_setz);
instance_template->Set("getDistance",
v8::FunctionTemplate::New(Vector_getDistance));
instance_template->Set("getLength",
v8::FunctionTemplate::New(Vector_getLength));
instance_template->Set("getNormalized",
v8::FunctionTemplate::New(Vector_getNormalized));
global->Set(v8::String::New("Vector"), function_template); // add
our Point object
}
}