2013-09-02 18:35:54 -04:00
|
|
|
PEP: 454
|
|
|
|
Title: Add a new tracemalloc module to trace Python memory allocations
|
|
|
|
Version: $Revision$
|
|
|
|
Last-Modified: $Date$
|
|
|
|
Author: Victor Stinner <victor.stinner@gmail.com>
|
|
|
|
Status: Draft
|
|
|
|
Type: Standards Track
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
Created: 3-September-2013
|
|
|
|
Python-Version: 3.4
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
========
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Add a new ``tracemalloc`` module to trace Python memory allocations.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
=========
|
|
|
|
|
|
|
|
This PEP proposes to a new ``tracemalloc`` module, a debug tool to trace
|
|
|
|
memory allocations made by Python. The module provides the following
|
|
|
|
information:
|
|
|
|
|
|
|
|
* Statistics on allocations per Python line number (file and line):
|
|
|
|
size, number, and average size of allocations
|
|
|
|
* Compute delta between two "snapshots"
|
|
|
|
* Location of a memory allocation: Python filename and line number
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
The ``tracemalloc`` module is different than other third-party modules
|
|
|
|
like ``Heapy`` or ``PySizer``, because it is focused on the location of
|
|
|
|
a memory allocation rather that the object type or object content.
|
|
|
|
|
|
|
|
|
|
|
|
API
|
|
|
|
===
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
To trace the most Python memory allocations, the module should be
|
|
|
|
enabled as early as possible in your application by calling
|
|
|
|
``tracemalloc.enable()`` function, by setting the ``PYTHONTRACEMALLOC``
|
|
|
|
environment variable to ``1``, or by using ``-X tracemalloc`` command
|
|
|
|
line option.
|
|
|
|
|
|
|
|
|
|
|
|
Functions
|
|
|
|
---------
|
|
|
|
|
|
|
|
enable():
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Start tracing Python memory allocations.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
disable():
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Stop tracing Python memory allocations and stop the timer started by
|
|
|
|
``start_timer()``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
is_enabled():
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Get the status of the module: ``True`` if it is enabled, ``False``
|
|
|
|
otherwise.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
get_object_trace(obj):
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Get the trace of a Python object *obj* as a namedtuple with 3 attributes:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
- ``size``: size in bytes of the object
|
|
|
|
- ``filename``: name of the Python script where the object was allocated
|
|
|
|
- ``lineno``: line number where the object was allocated
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Return ``None`` if tracemalloc did not save the location where the object
|
|
|
|
was allocated, for example if tracemalloc was disabled.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
get_process_memory():
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Get the memory usage of the current process as a meminfo namedtuple
|
|
|
|
with two attributes:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
* ``rss``: Resident Set Size in bytes
|
|
|
|
* ``vms``: size of the virtual memory in bytes
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Return ``None`` if the platform is not supported.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Use the ``psutil`` module if available.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
start_timer(delay: int, func: callable, args: tuple=(), kwargs: dict={}):
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Start a timer calling ``func(*args, **kwargs)`` every *delay*
|
|
|
|
seconds.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
The timer is based on the Python memory allocator, it is not real
|
|
|
|
time. *func* is called after at least *delay* seconds, it is not
|
|
|
|
called exactly after *delay* seconds if no Python memory allocation
|
|
|
|
occurred.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``start_timer()`` is called twice, previous parameters are
|
|
|
|
replaced. The timer has a resolution of 1 second.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
`start_timer()`` is used by ``DisplayTop`` and ``TakeSnapshot`` to
|
|
|
|
run regulary a task.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
stop_timer():
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Stop the timer started by ``start_timer()``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
2013-09-02 18:41:20 -04:00
|
|
|
DisplayTop class
|
|
|
|
----------------
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``DisplayTop(count: int, file=sys.stdout)`` class:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Display the list of the N biggest memory allocations.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``display()`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Display the top
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``start(delay: int)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Start a task using tracemalloc timer to display the top every delay seconds.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``stop()`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Stop the task started by the ``DisplayTop.start()`` method
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``color`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``display()`` uses colors if ``True`` (bool,
|
|
|
|
default: ``stream.isatty()``).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``compare_with_previous`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``True``, ``display()`` compares with the previous top if
|
|
|
|
``True``. If ``False``, compare with the first one (bool, default:
|
|
|
|
``True``): .
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``filename_parts`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
Number of displayed filename parts (int, default: ``3``).
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``show_average`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``True``, ``display()`` shows the average size of allocations
|
|
|
|
(bool, default: ``True``).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``show_count`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``True``, ``display()`` shows the number of allocations (bool, default: ``True``).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``show_lineno`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``True``, use also the line number, not only the filename (bool,
|
|
|
|
default: ``True``). If ``False``, only show the filename.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``show_size`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
If ``True``, ``display()`` shows the size of allocations (bool,
|
|
|
|
default: ``True``).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``user_data_callback`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Optional callback collecting user data (callable, default:
|
|
|
|
``None``). See ``Snapshot.create()``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
2013-09-02 18:41:20 -04:00
|
|
|
Snapshot class
|
|
|
|
--------------
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``Snapshot()`` class:
|
|
|
|
|
|
|
|
Snapshot of Python memory allocations. Use ``TakeSnapshot`` to
|
|
|
|
regulary take snapshots.
|
|
|
|
|
|
|
|
``create(user_data_callback=None)`` method:
|
|
|
|
|
|
|
|
Take a snapshot. If user_data_callback is specified, it must be a
|
|
|
|
callable object returning a list of (title: str, format: str, value:
|
|
|
|
int). format must be "size". The list must always have the same
|
|
|
|
length and the same order to be able to compute differences between
|
|
|
|
values.
|
|
|
|
|
|
|
|
Example: ``[('Video memory', 'size', 234902)]``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``filter_filenames(patterns: str|list, include: bool)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Remove filenames not matching any pattern if include is True, or
|
|
|
|
remove filenames matching a pattern if include is False (exclude).
|
|
|
|
See fnmatch.fnmatch() for the syntax of patterns.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``write(filename)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Write the snapshot into a file.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``load(filename)`` classmethod:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Load a snapshot from a file.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``process_memory`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Memory usage of the process, result of ``get_process_memory()``.
|
|
|
|
It can be ``None``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``user_data`` attribute:
|
2013-09-02 18:41:20 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Optional list of user data, result of *user_data_callback* in
|
|
|
|
``Snapshot.create()`` (default: None).
|
2013-09-02 18:41:20 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``pid`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Identifier of the process which created the snapshot (int).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``stats`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Raw memory allocation statistics (dict).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``timestamp`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Date and time of the creation of the snapshot (str).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
2013-09-02 18:41:20 -04:00
|
|
|
TakeSnapshot class
|
|
|
|
------------------
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``TakeSnapshot`` class:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Task taking snapshots of Python memory allocations: write them into files.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``start(delay: int)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Start a task taking a snapshot every delay seconds.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``stop()`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Stop the task started by the ``TakeSnapshot.start()`` method.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``take_snapshot()`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Take a snapshot.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``filename_template`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Template (str) to create a filename. "Variables" can be used in the
|
|
|
|
template:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
* ``$pid``: identifier of the current process
|
|
|
|
* ``$timestamp``: current date and time
|
|
|
|
* ``$counter``: counter starting at 1 and incremented at each snapshot
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
``user_data_callback`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
Optional callback collecting user data (callable, default: None).
|
|
|
|
See ``Snapshot.create()``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
|
Links
|
|
|
|
=====
|
|
|
|
|
2013-09-02 18:41:20 -04:00
|
|
|
Python issues:
|
|
|
|
|
|
|
|
* `#18874: Add a new tracemalloc module to trace Python
|
2013-09-02 18:35:54 -04:00
|
|
|
memory allocations <http://bugs.python.org/issue18874>`_
|
|
|
|
|
|
|
|
Similar projects:
|
|
|
|
|
|
|
|
* `Meliae: Python Memory Usage Analyzer
|
|
|
|
<https://pypi.python.org/pypi/meliae>`_
|
|
|
|
* `Issue #3329: API for setting the memory allocator used by Python
|
|
|
|
<http://bugs.python.org/issue3329>`_
|
|
|
|
* `Guppy-PE: umbrella package combining Heapy and GSL
|
|
|
|
<http://guppy-pe.sourceforge.net/>`_
|
|
|
|
* `PySizer <http://pysizer.8325.org/>`_: developed for Python 2.4
|
|
|
|
* `memory_profiler <https://pypi.python.org/pypi/memory_profiler>`_
|
|
|
|
* `pympler <http://code.google.com/p/pympler/>`_
|
|
|
|
* `Dozer <https://pypi.python.org/pypi/Dozer>`_: WSGI Middleware version of
|
|
|
|
the CherryPy memory leak debugger
|
|
|
|
* `objgraph <http://mg.pov.lt/objgraph/>`_
|
|
|
|
* `caulk <https://github.com/smartfile/caulk/>`_
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
=========
|
|
|
|
|
|
|
|
This document has been placed into the public domain.
|
|
|
|
|