[Python-Dev] PEP 454 (tracemalloc) disable ==> clear?

Victor Stinner victor.stinner at gmail.com
Thu Oct 31 13:20:48 CET 2013


2013/10/31 Victor Stinner <victor.stinner at gmail.com>:
> If I give access to this flag, it would be possible to disable
> temporarily tracing in the current thread, but tracing would still be
> enabled in other threads. Would it fit your requirement?

It's probably not what you are looking for :-)

As I wrote in the PEP, the API of tracemalloc was inspired by the
faulthandler module. enable() / disable() makes sense in faulthandler
because faulthandler is passive: it only do something on a trigger
(synchonous signals like SIGFPE or SIGSEGV). I realized that
tracemalloc is different: as written in the documentation, enable()
*starts* tracing. After enable() has been called, tracemalloc becomes
active. So tracemalloc should use names start() / stop() rather than
enable() / disable().

I did another experiment. I replaced enable/disable/is_enabled with
start/stop/is_tracing, and added enable/disable/is_enabled functions
to disable temporarily tracing.

API:

- clear_traces(): clear traces
- start(): start tracing (the old "enable")
- stop(): stop tracing and clear traces (the old "disable")
- disable(): disable temporarily tracing
- enable(): reenable tracing
- is_tracing(): True if tracemalloc is tracing, False otherwise (the
old "is_enabled")
- is_enabled(): True if tracemalloc is enabled, False otherwise

All these functions are process-wide (affect all threads).

tracemalloc is only tracing new allocations if is_tracing() and
is_enabled() are True.

If is_tracing() is True and is_enabled() is False, deallocations still
remove traces (otherwise, the internal dictionary of traces would
become inconsistent).

Example:
---------------
tracemalloc.start()
# start your application
...
useful = UsefulObject()
huge = HugeObject()
...
snapshot1 = take_snapshot()
...
# oh no, I don't want to trace this ugly object, but please don't
trash old traces
tracemalloc.disable()
ugly = ugly_object()
...
# release memory of the huge object
huge = None
...
# restart tracing (ugly is still alive)
tracemalloc.enable()
...
snapshot2 = take_snapshot()
tracemalloc.stop()
---------------

snapshot1 contains traces of objects:
- useful
- huge

snapshot2 contains traces of objects:
- useful

huge is missing from snapshot2 even if the module was disabled. ugly
is missing from snapshot2 because tracing was disabled.

Does it look better? I don't see the usecase of disable() / enable()
yet, but it's cheap (it just add a flag).

Victor


More information about the Python-Dev mailing list