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-10-08 09:54:15 -04:00
|
|
|
|
This PEP proposes to add a new ``tracemalloc`` module to trace memory
|
|
|
|
|
blocks allocated by Python.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
2013-10-22 07:57:53 -04:00
|
|
|
|
Classic generic tools like Valgrind can get the C traceback where a
|
|
|
|
|
memory block was allocated. Using such tools to analyze Python memory
|
|
|
|
|
allocations does not help because most memory blocks are allocated in
|
|
|
|
|
the same C function, in ``PyMem_Malloc()`` for example. Moreover, Python
|
|
|
|
|
has an allocator for small object called "pymalloc" which keeps free
|
|
|
|
|
blocks for efficiency. This is not well handled by these tools.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-09-03 20:02:50 -04:00
|
|
|
|
There are debug tools dedicated to the Python language like ``Heapy``
|
2013-10-22 07:57:53 -04:00
|
|
|
|
``Pympler`` and ``Meliae`` which lists all live objects using the
|
|
|
|
|
garbage module (functions like ``gc.get_objects()``,
|
|
|
|
|
``gc.get_referrers()`` and ``gc.get_referents()``), compute their size
|
|
|
|
|
(ex: using ``sys.getsizeof()``) and group objects by type. These tools
|
|
|
|
|
provide a better estimation of the memory usage of an application. They
|
|
|
|
|
are useful when most memory leaks are instances of the same type and
|
|
|
|
|
this type is only instantiated in a few functions. Problems arise when
|
|
|
|
|
the object type is very common like ``str`` or ``tuple``, and it is hard
|
|
|
|
|
to identify where these objects are instantiated.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-08 09:54:15 -04:00
|
|
|
|
Finding reference cycles is also a difficult problem. There are
|
|
|
|
|
different tools to draw a diagram of all references. These tools
|
|
|
|
|
cannot be used on large applications with thousands of objects because
|
|
|
|
|
the diagram is too huge to be analyzed manually.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Proposal
|
|
|
|
|
========
|
|
|
|
|
|
2013-10-08 09:54:15 -04:00
|
|
|
|
Using the customized allocation API from PEP 445, it becomes easy to
|
|
|
|
|
set up a hook on Python memory allocators. A hook can inspect Python
|
|
|
|
|
internals to retrieve Python tracebacks.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
This PEP proposes to add a new ``tracemalloc`` module, as a debug tool
|
|
|
|
|
to trace memory blocks allocated by Python. The module provides the
|
2013-09-03 19:19:30 -04:00
|
|
|
|
following information:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-08 09:54:15 -04:00
|
|
|
|
* Computed differences between two snapshots to detect memory leaks
|
2013-10-03 10:45:04 -04:00
|
|
|
|
* Statistics on allocated memory blocks per filename and per line
|
|
|
|
|
number: total size, number and average size of allocated memory blocks
|
|
|
|
|
* Traceback where a memory block was allocated
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-05 17:29:40 -04:00
|
|
|
|
The API of the tracemalloc module is similar to the API of the
|
|
|
|
|
faulthandler module: ``enable()``, ``disable()`` and ``is_enabled()``
|
|
|
|
|
functions, an environment variable (``PYTHONFAULTHANDLER`` and
|
2013-10-08 09:54:15 -04:00
|
|
|
|
``PYTHONTRACEMALLOC``), and a ``-X`` command line option (``-X
|
2013-09-05 17:29:40 -04:00
|
|
|
|
faulthandler`` and ``-X tracemalloc``). See the
|
|
|
|
|
`documentation of the faulthandler module
|
2013-10-08 09:54:15 -04:00
|
|
|
|
<http://docs.python.org/3/library/faulthandler.html>`_.
|
2013-09-05 17:23:35 -04:00
|
|
|
|
|
2013-10-22 07:57:53 -04:00
|
|
|
|
The idea of tracing memory allocations is not new. It was first
|
|
|
|
|
implemented in the PySizer project in 2005. PySizer was implemented
|
|
|
|
|
differently: the traceback was stored in frame objects and some Python
|
|
|
|
|
types were linked the trace with the name of object type. PySizer patch
|
|
|
|
|
on CPython adds a overhead on performances and memory footprint, even if
|
|
|
|
|
the PySizer was not used. tracemalloc attachs a traceback to the
|
|
|
|
|
underlying layer, to memory blocks, and has no overhead when the module
|
|
|
|
|
is disabled.
|
|
|
|
|
|
2013-09-05 17:26:55 -04:00
|
|
|
|
The tracemalloc module has been written for CPython. Other
|
2013-10-08 09:54:15 -04:00
|
|
|
|
implementations of Python may not be able to provide it.
|
2013-09-05 17:26:55 -04:00
|
|
|
|
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
|
API
|
|
|
|
|
===
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Main Functions
|
|
|
|
|
--------------
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``clear_traces()`` function:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Clear traces and statistics on Python memory allocations, and reset
|
|
|
|
|
the ``get_traced_memory()`` counter.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``disable()`` function:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Stop tracing Python memory allocations.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also ``enable()`` and ``is_enabled()`` functions.
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``enable()`` function:
|
2013-09-08 09:15:26 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Start tracing Python memory allocations.
|
2013-09-08 09:15:26 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
At fork, the module is automatically disabled in the child process.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also ``disable()`` and ``is_enabled()`` functions.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``get_stats()`` function:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Get statistics on traced Python memory blocks as a dictionary
|
|
|
|
|
``{filename (str): {line_number (int): stats}}`` where *stats* in a
|
|
|
|
|
``(size: int, count: int)`` tuple, *filename* and *line_number* can
|
|
|
|
|
be ``None``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return an empty dictionary if the ``tracemalloc`` module is
|
|
|
|
|
disabled.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also the ``get_traces()`` function.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``get_traced_memory()`` function:
|
|
|
|
|
|
|
|
|
|
Get the current size and maximum size of memory blocks traced by the
|
|
|
|
|
``tracemalloc`` module as a tuple: ``(size: int, max_size: int)``.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
``get_tracemalloc_memory()`` function:
|
|
|
|
|
|
|
|
|
|
Get the memory usage in bytes of the ``tracemalloc`` module as a
|
|
|
|
|
tuple: ``(size: int, free: int)``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
* *size*: total size of bytes allocated by the module,
|
|
|
|
|
including *free* bytes
|
|
|
|
|
* *free*: number of free bytes available to store data
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``is_enabled()`` function:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``True`` if the ``tracemalloc`` module is tracing Python memory
|
|
|
|
|
allocations, ``False`` otherwise.
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also ``enable()`` and ``disable()`` functions.
|
2013-09-08 09:15:26 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Trace Functions
|
|
|
|
|
---------------
|
2013-09-08 09:15:26 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``get_traceback_limit()`` function:
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Get the maximum number of frames stored in the traceback of a trace
|
|
|
|
|
of a memory block.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Use the ``set_traceback_limit()`` function to change the limit.
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-03 19:19:30 -04:00
|
|
|
|
``get_object_address(obj)`` function:
|
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Get the address of the main memory block of the specified Python object.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
A Python object can be composed by multiple memory blocks, the
|
|
|
|
|
function only returns the address of the main memory block.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
See also ``get_object_trace()`` and ``gc.get_referrers()`` functions.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-09-03 19:19:30 -04:00
|
|
|
|
``get_object_trace(obj)`` function:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Get the trace of a Python object *obj* as a ``(size: int,
|
2013-10-18 07:54:17 -04:00
|
|
|
|
traceback)`` tuple where *traceback* is a tuple of ``(filename: str,
|
|
|
|
|
lineno: int)`` tuples, *filename* and *lineno* can be ``None``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
The function only returns the trace of the main memory block of the
|
|
|
|
|
object. The *size* of the trace is smaller than the total size of
|
|
|
|
|
the object if the object is composed by more than one memory block.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return ``None`` if the ``tracemalloc`` module did not trace the
|
|
|
|
|
allocation of the object.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also ``get_object_address()``, ``get_trace()``,
|
|
|
|
|
``get_traces()``, ``gc.get_referrers()`` and ``sys.getsizeof()``
|
|
|
|
|
functions.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``get_trace(address)`` function:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Get the trace of a memory block as a ``(size: int, traceback)``
|
|
|
|
|
tuple where *traceback* is a tuple of ``(filename: str, lineno:
|
|
|
|
|
int)`` tuples, *filename* and *lineno* can be ``None``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return ``None`` if the ``tracemalloc`` module did not trace the
|
|
|
|
|
allocation of the memory block.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also ``get_object_trace()``, ``get_stats()`` and
|
|
|
|
|
``get_traces()`` functions.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``get_traces()`` function:
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Get traces of Python memory allocations as a dictionary ``{address
|
|
|
|
|
(int): trace}`` where *trace* is a ``(size: int, traceback)`` and
|
|
|
|
|
*traceback* is a list of ``(filename: str, lineno: int)``.
|
|
|
|
|
*traceback* can be empty, *filename* and *lineno* can be None.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Return an empty dictionary if the ``tracemalloc`` module is disabled.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
See also ``get_object_trace()``, ``get_stats()`` and ``get_trace()``
|
|
|
|
|
functions.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``set_traceback_limit(nframe: int)`` function:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Set the maximum number of frames stored in the traceback of a trace
|
|
|
|
|
of a memory block.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Storing the traceback of each memory allocation has an important
|
|
|
|
|
overhead on the memory usage. Use the ``get_tracemalloc_memory()``
|
|
|
|
|
function to measure the overhead and the ``add_filter()`` function
|
|
|
|
|
to select which memory allocations are traced.
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Use the ``get_traceback_limit()`` function to get the current limit.
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Filter Functions
|
|
|
|
|
----------------
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``add_filter(filter)`` function:
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Add a new filter on Python memory allocations, *filter* is a
|
|
|
|
|
``Filter`` instance.
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
All inclusive filters are applied at once, a memory allocation is
|
2013-10-18 07:54:17 -04:00
|
|
|
|
only ignored if no inclusive filters match its trace. A memory
|
2013-10-03 10:45:04 -04:00
|
|
|
|
allocation is ignored if at least one exclusive filter matchs its
|
|
|
|
|
trace.
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
The new filter is not applied on already collected traces. Use the
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``clear_traces()`` function to ensure that all traces match the new
|
|
|
|
|
filter.
|
2013-09-05 17:15:45 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``add_include_filter(filename: str, lineno: int=None, traceback: bool=False)`` function:
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Add an inclusive filter: helper for the ``add_filter()`` method
|
2013-10-18 07:54:17 -04:00
|
|
|
|
creating a ``Filter`` instance with the ``Filter.include`` attribute
|
|
|
|
|
set to ``True``.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Example: ``tracemalloc.add_include_filter(tracemalloc.__file__)``
|
2013-10-18 07:54:17 -04:00
|
|
|
|
only includes memory blocks allocated by the ``tracemalloc`` module.
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``add_exclude_filter(filename: str, lineno: int=None, traceback: bool=False)`` function:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Add an exclusive filter: helper for the ``add_filter()`` method
|
2013-10-18 07:54:17 -04:00
|
|
|
|
creating a ``Filter`` instance with the ``Filter.include`` attribute
|
|
|
|
|
set to ``False``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Example: ``tracemalloc.add_exclude_filter(tracemalloc.__file__)``
|
|
|
|
|
ignores memory blocks allocated by the ``tracemalloc`` module.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``clear_filters()`` function:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Reset the filter list.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also the ``get_filters()`` function.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``get_filters()`` function:
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Get the filters on Python memory allocations as list of ``Filter``
|
|
|
|
|
instances.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See also the ``clear_filters()`` function.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Filter
|
|
|
|
|
------
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``Filter(include: bool, pattern: str, lineno: int=None, traceback: bool=False)`` class:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Filter to select which memory allocations are traced. Filters can be
|
|
|
|
|
used to reduce the memory usage of the ``tracemalloc`` module, which
|
|
|
|
|
can be read using the ``get_tracemalloc_memory()`` function.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``match(filename: str, lineno: int)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return ``True`` if the filter matchs the filename and line number,
|
|
|
|
|
``False`` otherwise.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``match_filename(filename: str)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Return ``True`` if the filter matchs the filename, ``False`` otherwise.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``match_lineno(lineno: int)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return ``True`` if the filter matchs the line number, ``False``
|
|
|
|
|
otherwise.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``match_traceback(traceback)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Return ``True`` if the filter matchs the *traceback*, ``False``
|
|
|
|
|
otherwise.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
*traceback* is a tuple of ``(filename: str, lineno: int)`` tuples.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
|
|
|
|
``include`` attribute:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If *include* is ``True``, only trace memory blocks allocated in a
|
|
|
|
|
file with a name matching filename ``pattern`` at line number
|
|
|
|
|
``lineno``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If *include* is ``False``, ignore memory blocks allocated in a file
|
2013-10-18 07:54:17 -04:00
|
|
|
|
with a name matching filename ``pattern`` at line number ``lineno``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
``lineno`` attribute:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Line number (``int``). If is is ``None`` or less than ``1``, it
|
|
|
|
|
matches any line number.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
|
|
|
|
``pattern`` attribute:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
The filename *pattern* can contain one or many ``*`` joker
|
|
|
|
|
characters which match any substring, including an empty string. The
|
|
|
|
|
``.pyc`` and ``.pyo`` file extensions are replaced with ``.py``. On
|
|
|
|
|
Windows, the comparison is case insensitive and the alternative
|
|
|
|
|
separator ``/`` is replaced with the standard separator ``\``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
``traceback`` attribute:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If *traceback* is ``True``, all frames of the traceback are checked.
|
|
|
|
|
If *traceback* is ``False``, only the most recent frame is checked.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
This attribute is ignored if the traceback limit is less than ``2``.
|
|
|
|
|
See the ``get_traceback_limit()`` function.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
GroupedStats
|
|
|
|
|
------------
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``GroupedStats(timestamp: datetime.datetime, stats: dict, group_by: str, cumulative=False, metrics: dict=None)`` class:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Top of allocated memory blocks grouped by *group_by* as a
|
|
|
|
|
dictionary.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
The ``Snapshot.top_by()`` method creates a ``GroupedStats``
|
|
|
|
|
instance.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``compare_to(old_stats: GroupedStats=None)`` method:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Compare to an older ``GroupedStats`` instance. Return a
|
|
|
|
|
``StatsDiff`` instance.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
The ``StatsDiff.differences`` list is not sorted: call the
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``StatsDiff.sort()`` method to sort the list.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
``None`` values are replaced with an empty string for filenames or
|
|
|
|
|
zero for line numbers, because ``str`` and ``int`` cannot be
|
|
|
|
|
compared to ``None``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``cumulative`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If ``True``, cumulate size and count of memory blocks of all frames
|
|
|
|
|
of the traceback of a trace, not only the most recent frame.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``metrics`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Dictionary storing metrics read when the snapshot was created:
|
|
|
|
|
``{name (str): metric}`` where *metric* type is ``Metric``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``group_by`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Determine how memory allocations were grouped: see
|
|
|
|
|
``Snapshot.top_by()`` for the available values.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``stats`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Dictionary ``{key: stats}`` where the *key* type depends on the
|
|
|
|
|
``group_by`` attribute and *stats* is a ``(size: int, count: int)``
|
|
|
|
|
tuple.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
See the ``Snapshot.top_by()`` method.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``timestamp`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Creation date and time of the snapshot, ``datetime.datetime``
|
|
|
|
|
instance.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Metric
|
|
|
|
|
------
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``Metric(name: str, value: int, format: str)`` class:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Value of a metric when a snapshot is created.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``name`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Name of the metric.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``value`` attribute:
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Value of the metric.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``format`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Format of the metric (``str``).
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-02 18:53:13 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
Snapshot
|
|
|
|
|
--------
|
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``Snapshot(timestamp: datetime.datetime, traces: dict=None, stats: dict=None)`` class:
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Snapshot of traces and statistics on memory blocks allocated by Python.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
|
|
|
|
``add_metric(name: str, value: int, format: str)`` method:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Helper to add a ``Metric`` instance to ``Snapshot.metrics``. Return
|
|
|
|
|
the newly created ``Metric`` instance.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Raise an exception if the name is already present in
|
|
|
|
|
``Snapshot.metrics``.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``apply_filters(filters)`` method:
|
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Apply filters on the ``traces`` and ``stats`` dictionaries,
|
|
|
|
|
*filters* is a list of ``Filter`` instances.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``create(traces=False)`` classmethod:
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Take a snapshot of traces and/or statistics of allocated memory blocks.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
If *traces* is ``True``, ``get_traces()`` is called and its result
|
|
|
|
|
is stored in the ``Snapshot.traces`` attribute. This attribute
|
|
|
|
|
contains more information than ``Snapshot.stats`` and uses more
|
|
|
|
|
memory and more disk space. If *traces* is ``False``,
|
|
|
|
|
``Snapshot.traces`` is set to ``None``.
|
2013-09-16 19:38:43 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Tracebacks of traces are limited to ``traceback_limit`` frames. Call
|
|
|
|
|
``set_traceback_limit()`` before calling ``Snapshot.create()`` to
|
|
|
|
|
store more frames.
|
2013-09-02 18:53:13 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
The ``tracemalloc`` module must be enabled to take a snapshot. See
|
2013-10-03 11:47:02 -04:00
|
|
|
|
the the ``enable()`` function.
|
2013-09-02 18:53:13 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``get_metric(name, default=None)`` method:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Get the value of the metric called *name*. Return *default* if the
|
|
|
|
|
metric does not exist.
|
2013-09-03 07:18:48 -04:00
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``load(filename, traces=True)`` classmethod:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Load a snapshot from a file.
|
2013-10-03 10:00:07 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If *traces* is ``False``, don't load traces.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``top_by(group_by: str, cumulative: bool=False)`` method:
|
2013-09-02 18:41:20 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Compute top statistics grouped by *group_by* as a ``GroupedStats``
|
|
|
|
|
instance:
|
2013-09-02 18:41:20 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
===================== ======================== ================================
|
2013-10-03 10:45:04 -04:00
|
|
|
|
group_by description key type
|
2013-10-18 07:54:17 -04:00
|
|
|
|
===================== ======================== ================================
|
2013-10-03 10:45:04 -04:00
|
|
|
|
``'filename'`` filename ``str``
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``'line'`` filename and line number ``(filename: str, lineno: int)``
|
2013-10-03 10:45:04 -04:00
|
|
|
|
``'address'`` memory block address ``int``
|
2013-10-18 07:54:17 -04:00
|
|
|
|
``'traceback'`` traceback ``(address: int, traceback)``
|
|
|
|
|
===================== ======================== ================================
|
|
|
|
|
|
|
|
|
|
The ``traceback`` type is a tuple of ``(filename: str, lineno:
|
|
|
|
|
int)`` tuples, *filename* and *lineno* can be ``None``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
If *cumulative* is ``True``, cumulate size and count of memory
|
|
|
|
|
blocks of all frames of the traceback of a trace, not only the most
|
|
|
|
|
recent frame. The *cumulative* parameter is ignored if *group_by*
|
|
|
|
|
is ``'address'`` or if the traceback limit is less than ``2``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``write(filename)`` method:
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
Write the snapshot into a file.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``metrics`` attribute:
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Dictionary storing metrics read when the snapshot was created:
|
|
|
|
|
``{name (str): metric}`` where *metric* type is ``Metric``.
|
2013-09-08 09:58:01 -04:00
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
``stats`` attribute:
|
2013-09-03 19:19:30 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Statistics on traced Python memory, result of the ``get_stats()``
|
|
|
|
|
function.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``traceback_limit`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Maximum number of frames stored in a trace of a memory block
|
|
|
|
|
allocated by Python.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``traces`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Traces of Python memory allocations, result of the ``get_traces()``
|
|
|
|
|
function, can be ``None``.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``timestamp`` attribute:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Creation date and time of the snapshot, ``datetime.datetime``
|
|
|
|
|
instance.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
|
2013-10-03 10:00:07 -04:00
|
|
|
|
StatsDiff
|
|
|
|
|
---------
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``StatsDiff(differences, old_stats, new_stats)`` class:
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Differences between two ``GroupedStats`` instances.
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-18 07:54:17 -04:00
|
|
|
|
The ``GroupedStats.compare_to()`` method creates a ``StatsDiff``
|
2013-10-03 10:45:04 -04:00
|
|
|
|
instance.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``sort()`` method:
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Sort the ``differences`` list from the biggest difference to the
|
|
|
|
|
smallest difference. Sort by ``abs(size_diff)``, *size*,
|
|
|
|
|
``abs(count_diff)``, *count* and then by *key*.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``differences`` attribute:
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Differences between ``old_stats`` and ``new_stats`` as a list of
|
|
|
|
|
``(size_diff, size, count_diff, count, key)`` tuples. *size_diff*,
|
|
|
|
|
*size*, *count_diff* and *count* are ``int``. The key type depends
|
2013-10-18 07:54:17 -04:00
|
|
|
|
on the ``GroupedStats.group_by`` attribute of ``new_stats``: see the
|
|
|
|
|
``Snapshot.top_by()`` method.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``old_stats`` attribute:
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
Old ``GroupedStats`` instance, can be ``None``.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-09-16 19:38:43 -04:00
|
|
|
|
``new_stats`` attribute:
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-10-03 10:45:04 -04:00
|
|
|
|
New ``GroupedStats`` instance.
|
2013-09-04 07:19:17 -04:00
|
|
|
|
|
2013-09-03 07:18:48 -04:00
|
|
|
|
|
2013-10-21 20:30:12 -04:00
|
|
|
|
Prior Work
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
* `Python Memory Validator
|
|
|
|
|
<http://www.softwareverify.com/python/memory/index.html>`_ (2005-2013):
|
|
|
|
|
commercial Python memory validator developed by Software Verification.
|
|
|
|
|
It uses the Python Reflection API.
|
|
|
|
|
* `PySizer <http://pysizer.8325.org/>`_: Google Summer of Code 2005 project by
|
|
|
|
|
Nick Smallbone.
|
|
|
|
|
* `Heapy
|
|
|
|
|
<http://guppy-pe.sourceforge.net/>`_ (2006-2013):
|
|
|
|
|
part of the Guppy-PE project written by Sverker Nilsson.
|
|
|
|
|
* Draft PEP: `Support Tracking Low-Level Memory Usage in CPython
|
|
|
|
|
<http://svn.python.org/projects/python/branches/bcannon-sandboxing/PEP.txt>`_
|
|
|
|
|
(Brett Canon, 2006)
|
|
|
|
|
* Muppy: project developed in 2008 by Robert Schuppenies.
|
|
|
|
|
* `asizeof <http://code.activestate.com/recipes/546530/>`_:
|
|
|
|
|
a pure Python module to estimate the size of objects by Jean
|
|
|
|
|
Brouwers (2008).
|
|
|
|
|
* `Heapmonitor <http://www.scons.org/wiki/LudwigHaehne/HeapMonitor>`_:
|
|
|
|
|
It provides facilities to size individual objects and can track all objects
|
|
|
|
|
of certain classes. It was developed in 2008 by Ludwig Haehne.
|
|
|
|
|
* `Pympler <http://code.google.com/p/pympler/>`_ (2008-2011):
|
|
|
|
|
project based on asizeof, muppy and HeapMonitor
|
|
|
|
|
* `objgraph <http://mg.pov.lt/objgraph/>`_ (2008-2012)
|
|
|
|
|
* `Dozer <https://pypi.python.org/pypi/Dozer>`_: WSGI Middleware version
|
|
|
|
|
of the CherryPy memory leak debugger, written by Marius Gedminas (2008-2013)
|
|
|
|
|
* `Meliae
|
|
|
|
|
<https://pypi.python.org/pypi/meliae>`_:
|
|
|
|
|
Python Memory Usage Analyzer developed by John A Meinel since 2009
|
|
|
|
|
* `caulk <https://github.com/smartfile/caulk/>`_: written by Ben Timby in 2012
|
|
|
|
|
* `memory_profiler <https://pypi.python.org/pypi/memory_profiler>`_:
|
|
|
|
|
written by Fabian Pedregosa (2011-2013)
|
|
|
|
|
|
|
|
|
|
See also `Pympler Related Work
|
|
|
|
|
<http://pythonhosted.org/Pympler/related.html>`_.
|
|
|
|
|
|
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
|
Links
|
|
|
|
|
=====
|
|
|
|
|
|
2013-09-04 08:01:56 -04:00
|
|
|
|
tracemalloc:
|
2013-09-02 18:41:20 -04:00
|
|
|
|
|
|
|
|
|
* `#18874: Add a new tracemalloc module to trace Python
|
2013-09-02 18:35:54 -04:00
|
|
|
|
memory allocations <http://bugs.python.org/issue18874>`_
|
2013-09-04 08:01:56 -04:00
|
|
|
|
* `pytracemalloc on PyPI
|
|
|
|
|
<https://pypi.python.org/pypi/pytracemalloc>`_
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
2013-10-08 09:54:15 -04:00
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
2013-09-02 18:35:54 -04:00
|
|
|
|
|
2013-10-08 09:54:15 -04:00
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|