What is the most reliable way to register a clean up when a Python object's ref count reaches zero?

Viewed 135

I have a Python client application that communicates with a server. When an object is no longer used on the client side (i.e. ref count reaches zero - using CPython), I need to send a message to the server so it could clean the corresponding memory.

From Python's data model page __del__ documentation, I know that the mentioned special method is called when the ref count reaches zero, so implementing it to send a message to the server would possibly suffice.

I wanted to ask whether there is a more reliable approach, possibly by using the garbage collector (perhaps by adding a callback using gc.callbacks). I'm not sure if all Python objects are handled by it though.

Any help on the most robust way to call clean ups after an object is no longer referenced would be appreciated.

1 Answers

First thing to know is that the "garbage collection" (gc) module in CPython exists solely to collect trash caught in reference cycles. In most programs, almost all trash is reclaimed by reference counting alone, and gc has nothing to do with it. In fact, I have a number of long-running programs I know don't create cyclic trash, and I start them with gc.disable(). They can run then for days without leaking memory - refcounting alone (which cannot be disabled) is all they need to reclaim all the significant trash they create.

So, no, thinking about gc at all is mostly a red herring here.

__del__() is the best hook you have. That's why it exists: to give you a way to do something when CPython learns that an object is trash.

That doesn't mean it's bulletproof, but then nothing can be. For example, if the OS kills your program (via, e.g, SIGKILL on Linux), your program ends at once, with no chance to perform any cleanup actions.

An alternative is to use weakref.finalize(obj, callback, ...) to register a callback to be invoked when a weakly-referencable object obj becomes trash. That has the sometimes-benefit of arranging (by default) for the atexit module to run the callback during the normal interpreter shutdown sequence even if the object is still alive then. See the weakref module's

"Comparing finalizers with __del__() methods"

section for more on that.

Related