🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Leak occurs when "shared class" exists.

Started by
4 comments, last by WitchLord 6 years, 2 months ago

Leak occurs when "shared class" exists.

`destructor` of asIScriptFunction will not be called, so I
investigated it,

I applied the following patch and improved it.


bool asCModule::HasExternalReferences(bool shuttingDown)
    :
    :
 	for( asUINT n = 0; n < classTypes.GetLength(); n++ )
 		if( classTypes[n] && classTypes[n]->externalRefCount.get() )
 		{
+            asCObjectType *type = classTypes[n];
+            if( type->IsShared() )
+                continue;

.... Should I also check below?

              if( engine->FindNewOwnerForSharedType(type, this) != this )

 

Advertisement

I doubt the leak happens just because of the existence of 'shared class'. Can you provide some code that reproduces this memory leak?

I need to be able to reproduce the problem in order to do the investigation and come up with the correct solution.

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


asCScriptFunction::~asCScriptFunction()
{
	// Dummy functions that are allocated on the stack are not reference counted
	asASSERT( funcType == asFUNC_DUMMY    ||
		      (externalRefCount.get() == 0 && internalRefCount.get() == 0) );

+    printf("  + destruct %s\n", name.AddressOf());fflush(stdout);

First of all, prepare as above.


static const char *script1 =
"shared class X { } \n"
"X@ x = X();"
  ;

static const char *script2 = 
"shared class X { };  \n"
"void test() {              \n"
"}                          \n"
  ;

bool Test()
{
	bool fail = false;
	int r;
	CBufferedOutStream out;

 	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &out, asCALL_THISCALL);

	asIScriptModule *mod = engine->GetModule("Module1", asGM_ALWAYS_CREATE);
	mod->AddScriptSection("Script1", script1, strlen(script1), 0);
	mod->Build();

	out.buffer = "";
	mod = engine->GetModule("Module2", asGM_ALWAYS_CREATE);
	mod->AddScriptSection("Script2", script2, strlen(script2), 0);
	r = mod->Build();
	if( r < 0 ) TEST_FAILED;
	if( out.buffer != "" )
		TEST_FAILED;

	// discard `Module2`
	mod->Discard();

	// game loop
	for(unsigned i = 0; i < 10; ++i) { 
		engine->GarbageCollect(); // run DeleteDiscardedModules();
		PRINTF(".");
	}
	PRINTF("gameloop done.\n");
    
	engine->Release();

	// Success
	return fail;
}

And then execute the above.


..........gameloop done.
  + destruct test

The result will be as above. This indicates that `void test ()` was
not deleted until the game loop terminated.


  + destruct test
..........gameloop done.

Applying a patch to `asCModule :: HasExternalReferences` will result
in the above.

Thanks. I understand what you mean now. It's not really a leak, just the memory clean up isn't happening as soon as it could. 

I'll look into it.

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

I've fixed this in revision 2490.

This was a very nice catch. Memory build-up is very difficult to find as memory leak test tools don't report these as leaks. 

Thanks a lot for reporting it.

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