Garbage Collection for "accept" (message table), actors, and loaders (models loader from loader)? (Answered)


#1

Hello, it has been a couple of days, but I have recently ran into a error that has gave me the motivation to ask this, and that is, what is the proper way to clean up (garbage collect) panda events ex:(fn-again-in, self.eventfnct) from the messenger table, actors with all the animations, and models loaded from the loader function.

Now I,am really asking if I,m doing this right, from what I read on these forums, you need to delete a actor by calling on delete? is this correct? what about something loaded from the loader command? looking at “serega-kkz”'s (a member of this community) code example he gave me from a another topic.

It suggests that I detach and remove the nodes to completely remove anything loaded from the loader function, so does this method work with the actor? or do I delete as suggested by many in this forum? and what about the “accept events” how are those garbage collected, I tired using the ignore command exactly like the accept command and I got the error.

So I would be vary grateful for some clarity on this topic, as I have been working on garbage collection for a while, so with that been said, thank you to anyone who is willing to help.


#2

Normally, detaching a node from the scene graph will be enough to garbage collect it. However, by default, models are also cached in the model-cache, and you may need to call loader.unloadModel to unload it from the cache (or disable caching when loading the model).

As for Actor, this is a Python structure that maintains additional information on top, so it is wise to call actor.cleanup() before letting it go out of scope.

I am not quite sure about DirectObject; in theory it should be possible for Python’s cyclic garbage collection system to find circular references, but it is probably wise to call ignoreAll() explicitly before letting it go out of scope.


#3

One minor point of clarification: is “detachNode” enough for a non-Actor node? I was under the impression that “removeNode” was called for, as “detachNode” doesn’t actually clean up the contents of the node. But perhaps that’s only the case if the developer doesn’t keep a reference to the detached node?


#4

@Thaumaturge removeNode() is equivalent to detachNode() followed by clear(). Neither “cleans up the contents of the node”; but clear() removes the reference to the node, ie. turning the NodePath into an empty NodePath, similar to just letting the NodePath object fall out of scope.

There’s no real difference, really, if you let the NodePath go out of scope anyway. Maybe we should remove one or the other and just tell people to use this instead:

nodepath.detachNode()
nodepath = None

#5

Ah, fair enough! Thank you for clarifying that. :slight_smile:


#6

So cleanup() will do the trick? is there a one all command for this or do I have to do it step by step with multiple commands?, I,m concerned over the ignoreAll() command as I have accept events for the main character and key controls.

At the moment I,m attempting to use single ignore commands to filter out the important accept events like I listed above, is this okay? I guess you are probably wonder why I,m asking this if I,m providing suggestions myself, it’s because I do not know what is going on regarding garbage collection,as the few debugging features I found are not sufficient.

So I,m asking professionals to reduce my chance of error as I have to do this almost blind and hope nothing goes wrong, so this may be trial and error for me, so I apologize in advance if I.m bothersome with all these questions that I may have to ask soon, anyway thanks rdb for the information, I,m going to try right now.


#7

cleanup() will do the trick for an Actor, though the model may still be in the model cache, so unloadModel may also be needed.

You can use separate DirectObjects for different “groups” of events, so that you can easily “ignoreAll” one set while keeping another intact. Otherwise, you can make two methods, one for accepting your events and one for ignoring them, where you call .ignore('a') etc on each event. But, if you work with separate classes that each inherit from DirectObject, it is easier to just call ignoreAll.

There are probably Python debugging tools that can help you with figuring out leaks in your garbage collection.


#8

Grouping? how would you put objects into groups? that sounds so much easier, sorry, I was not being clear enough, what I meant by debugging tools was on panda3d’s end as it is the system handling the actors, loaders, and messenger table, is there any commands to reveal information about this stuff?

Right now, I,m using “render.analyze()” to reveal the number of nodes in use, but are there others? what about the messenger table? anyway thanks for the response.


#9

Okay, so after a day of experimenting, it seems rdb’s detach and flagging of it’s container as “None” works for me when modified with removeNode() instead of detach, using “render.analyze()” I was able to check and compare the number of nodes and this method seems to get rid of all but one.

Maybe that node can be found later, but sadly, I did try clear() method, and it made things much worse in fact, it did not wash away the nodes and piled them up doubling the node count and the strange crashing glitch from this thread

Has reappeared from it, anyway this solution seems to work, though I get some slow down some time after the cleanup is done, which scares living heck out of me as it was a prelude to the said glitch in the above thread.

But so far it seems to be working for the time being, thank you rdb, your information seems to be enough to answer my question.