Advertisement

Releasing script object but no delete :/

Started by May 21, 2009 04:33 PM
3 comments, last by WitchLord 15 years, 6 months ago
I am only adding a single reference to my script object on the application side (during construction where I instantiate it). And during the application side object's destruct or, I call release() on that same Script object. There are no script side objects holding or adding references to it either, and yet, when I call release it has between 1 and 2 references left :/ What else could be adding references to it? I call a few methods on it, but nothing takes it as an argument or anything like that. *edit* I just noticed, after constructing my script object, I add a reference to it for my application, and right then it already has 3. Why is that? *edit* *edit* Ah I found the engine ReleaseScriptObject() method, so now my cleanup looks like this:

    asIScriptEngine* engine = m_scriptObject->GetEngine();
    engine->ReleaseScriptObject( m_scriptObject,m_scriptObject->GetTypeId() );
    m_scriptObject->Release();



And this *works* but is this how it is intended to be done? *edit* *edit* *edit* Well, while the above method seems to work, when the script engine is cleaned up at the end of the program (it is held by a global, so it happens when globals are being cleaned up at the end), I get a crash, leading me to believe maybe this isn't how I should be cleaning up these script objects. This is how I clean things up at the end:

ScriptEngine::~ScriptEngine() {
    m_context->Release();
    m_engine->Release();
}


And this is the stack trace I get when it crashes:
Quote: #0 0052B155 asCScriptEngine::CallObjectMethod(this=0x2c83d00, obj=0x64e2288, i=0x2c86320, s=0x2c86550) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:2867) #1 0052B1FF asCScriptEngine::CallObjectMethod(this=0x2c83d00, obj=0x64e2288, func=16) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:2839) #2 00548F24 asCGarbageCollector::IdentifyGarbageWithCyclicRefs(this=0x2c8401c) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_gc.cpp:298) #3 0054979D asCGarbageCollector::GarbageCollect(this=0x2c8401c, flags=asGC_FULL_CYCLE) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_gc.cpp:90) #4 0052A184 asCScriptEngine::GarbageCollect(this=0x2c83d00, flags=asGC_FULL_CYCLE) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:3191) #5 0053564C asCScriptEngine::Reset(this=0x2c83d00) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:519) #6 00536F26 asCScriptEngine::~asCScriptEngine(this=0x2c83d00) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:361) #7 0053584F asCScriptEngine::Release(this=0x2c83d00) (C:/code/libraries/AngelScript_svn/sdk/angelscript/source/as_scriptengine.cpp:496) #8 004314BA ScriptEngine::~ScriptEngine(this=0x742520) (C:/code/TowerDefense/TowerDefenseCommon/ScriptEngine.cpp:159) #9 00432DC2 __static_initialization_and_destruction_0(__initialize_p=0, __priority=65535) (C:/code/TowerDefense/TowerDefenseCommon/ScriptEngine.cpp:14) #10 00432DE5 global destructors keyed to gScriptEngine() (C:/code/TowerDefense/TowerDefenseCommon/ScriptEngine.cpp:357) #11 005B8132 __do_global_dtors() (./boost/system/error_code.hpp:212) #12 761C1FEF msvcrt!_flushall() (C:\Windows\syswow64\msvcrt.dll:??) #13 00000000 0x3923e76b in ??() (??:??) #14 00000000 0x00000000 in ??() (??:??)
any ideas? [Edited by - Wavesonics on May 21, 2009 7:00:22 PM]
==============================
A Developers Blog | Dark Rock Studios - My Site
Please read the following pages in the manual for the long answer: Garbage Collection and Memory managment.

The short answer is that your script class is declared in a way that can potentially make it form circular references (probably it has an object handle as a member property), this tells the GC to hold a reference to the object so that it can check for circular references.

You need to manually invoke the GC with a call to engine->GarbageCollect(). It is a manual action so you can choose the most appropriate moment for it, where it will impact the performance of your application the least.

---

asIScriptEngine::ReleaseScriptObject() does the same as asIScriptObject::Release() for script classes. The engine method is just a way to allow you to release references without having the application knowing the actual C++ method to call.

It seemed to work for you, because when you added that call you actually released the GC's reference to the object which deleted the object. But then crashed the application as the GC tried to release it's own reference for the now invalid object.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
aaahhhh thanks a million whitchlord, your a real life saver :)

I had read that doc, but was skimming and didn't get the right thing out of it I guess.
==============================
A Developers Blog | Dark Rock Studios - My Site
Btw, on MinGW/GCC 4.1.2 (target: Win32) the following (which is from the GC man page) produces a compile time error:

engine->GarbageCollect(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE);


Quote:
error: invalid conversion from 'int' to 'asEGCFlags'|
error: initializing argument 1 of 'virtual int asIScriptEngine::GarbageCollect(asEGCFlags)'|


But
engine->GarbageCollect( asGC_FULL_CYCLE );// orengine->GarbageCollect( (asEGCFlags)(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE) );

are of course fine.
==============================
A Developers Blog | Dark Rock Studios - My Site
Thanks. I'll have to change the argument type to asDWORD in a future version.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement