Jump to content

How does Garbage Collection work?


Harmlezz

Recommended Posts

I have observed a strange (or at least unexpected) behavior and would like to hear how it really works. What i did:

 

I do have a scripted item i do remove immediately when the script starts to run. I have introduced a guard to ensure the item is evaluated only once. But even after 200 Frames sometimes the item gets still processed. Here a snippet of my script with debugging statements:

 

int inProgress

int hasBeenRemoved

int tokenCount

int frameCount

 

Begin GameMode

if (inProgress == 0)

set inProgress to 1

 

; some code goes here

 

set hasBeenRemoved to 1

set container to getContainer

container.removeItem MyToken 1

return

endif

 

set frameCount to frameCount + 1

 

if (frameCount >= 200)

set container to getContainer

set tokenCount to container.getItemCount MyToken

showMessage DebugMessage tokenCount hasBeenRemoved

container.removeItem MyToken tokenCount

endif
End

What I observe is that sometimes (half the times probably) the second if - endif block gets executed. As far as I do understand the Engine did ran the script 200 times. The message i show always has

 

tokenCount == 1

and

hasBeenRemoved == 1

 

That means the item was already removed, but the Engine still runs the item script. So my expectation was a synchronous garbage collection of item but derived from my observations i guess the item get asynchronous garbage collected, someone in the future. Who knows for sure what the reason for this behavior is?

 

Thanks a lot in advance, Harmlezz

Link to comment
Share on other sites

It's a good idea to guard everything, and also not to assume that things happen instantly within one frame.

To make sure that the object is actually removing itself, use removeme (in the event of multiple instances in the container).

 

int inProgress
int hasBeenRemoved
int tokenCount
int frameCount

Begin GameMode

if hasBeenRemoved
	return
else
	if (inProgress == 0)
		set inProgress to 1

		; some code goes here

		set hasBeenRemoved to 1
		removeme
		return
	endif

endif

End

Link to comment
Share on other sites

It's a good idea to guard everything, and also not to assume that things happen instantly within one frame.

To make sure that the object is actually removing itself, use removeme (in the event of multiple instances in the container).

 

int inProgress
int hasBeenRemoved
int tokenCount
int frameCount

Begin GameMode

if hasBeenRemoved
	return
else
	if (inProgress == 0)
		set inProgress to 1

		; some code goes here

		set hasBeenRemoved to 1
		removeme
		return
	endif

endif

End

 

I didn't used removeme because of this note in the G.E.C.K. Wiki:

 

In Fallout3.esm the only usage of this function is inside OnAdd blocks. If used outside of this block, RemoveMe may crash the game. Use DropMe instead.

 

The variable inProgress does exactly this. The variable hasBeenRemoved I introduced only to observe my code piece by piece and in my opinion it is not required (and has been already removed).

Edited by Harmlezz
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...