Skip to main content

A memory profiler for Python applications

Project description


OS Linux PyPI - Python Version PyPI - Implementation PyPI PyPI - Downloads Tests Code Style

Memray output

Memray is a memory profiler for Python. It can track memory allocations in Python code, in native extension modules, and in the Python interpreter itself. It can generate several different types of reports to help you analyze the captured memory usage data. While commonly used as a CLI tool, it can also be used as a library to perform more fine-grained profiling tasks.

Notable features:

  • 🕵️‍♀️ Traces every function call so it can accurately represent the call stack, unlike sampling profilers.
  • ℭ Also handles native calls in C/C++ libraries so the entire call stack is present in the results.
  • 🏎 Blazing fast! Profiling slows the application only slightly. Tracking native code is somewhat slower, but this can be enabled or disabled on demand.
  • 📈 It can generate various reports about the collected memory usage data, like flame graphs.
  • 🧵 Works with Python threads.
  • 👽🧵 Works with native-threads (e.g. C++ threads in C extensions).

Memray can help with the following problems:

  • Analyze allocations in applications to help discover the cause of high memory usage.
  • Find memory leaks.
  • Find hotspots in code that cause a lot of allocations.

Note that Memray only works on Linux and cannot be installed on other platforms.

Installation

Memray requires Python 3.7+ and can be easily installed using most common Python packaging tools. We recommend installing the latest stable release from PyPI with pip:

    python3 -m pip install memray

Notice that Memray contains a C extension so releases are distributed as binary wheels as well as the source code. If a binary wheel is not available for your system (Linux x86/x64), you'll need to ensure that all the dependencies are satisfied on the system where you are doing the installation.

Building from source

If you wish to build Memray from source you need the following binary dependencies in your system:

  • libunwind
  • liblz4

Check your package manager on how to install these dependencies (for example apt-get install libunwind-dev liblz4-dev in Debian-based systems).

Once you have the binary dependencies installed, you can clone the repository and follow with the normal building process:

git clone git@github.com:bloomberg/memray.git memray
cd memray
python3 -m venv ../memray-env/  # just an example, put this wherever you want
source ../memray-env/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e . -r requirements-test.txt -r requirements-extra.txt

This will install Memray in the virtual environment in development mode (the -e of the last pip install command).

Documentation

You can find the latest documentation available here.

Usage

There are many ways to use Memray. The easiest way is to use it as a command line tool to run your script, application, or library.

usage: memray [-h] [-v] {run,flamegraph,table,live,tree,parse,summary,stats} ...

Memory profiler for Python applications

Run `memray run` to generate a memory profile report, then use a reporter command
such as `memray flamegraph` or `memray table` to convert the results into HTML.

Example:

    $ python3 -m memray run -o output.bin my_script.py
    $ python3 -m memray flamegraph output.bin

positional arguments:
  {run,flamegraph,table,live,tree,parse,summary,stats}
                        Mode of operation
    run                 Run the specified application and track memory usage
    flamegraph          Generate an HTML flame graph for peak memory usage
    table               Generate an HTML table with all records in the peak memory usage
    live                Remotely monitor allocations in a text-based interface
    tree                Generate a tree view in the terminal for peak memory usage
    parse               Debug a results file by parsing and printing each record in it
    summary             Generate a terminal-based summary report of the functions that allocate most memory
    stats               Generate high level stats of the memory usage in the terminal

optional arguments:
  -h, --help            Show this help message and exit
  -v, --verbose         Increase verbosity. Option is additive and can be specified up to 3 times

Please submit feedback, ideas, and bug reports by filing a new issue at https://github.com/bloomberg/memray/issues

To use Memray over a script or a single python file you can use

python3 -m memray run my_script.py

If you normally run your application with python3 -m my_module, you can use the -m flag with memray run:

python3 -m memray run -m my_module

You can also invoke Memray as a command line tool without having to use -m to invoke it as a module:

memray run my_script.py
memray run -m my_module

The output will be a binary file (like memray-my_script.2369.bin) that you can analyze in different ways. One way is to use the memray flamegraph command to generate a flame graph:

memray flamegraph my_script.2369.bin

This will produce an HTML file with a flame graph of the memory usage that you can inspect with your favorite browser. There are multiple other reporters that you can use to generate other types of reports, some of them generating terminal-based output and some of them generating HTML files. Here is an example of a Memray flamegraph:

Pytest plugin

If you want an easy and convenient way to use memray in your test suite, you can consider using pytest-memray. Once installed, this pytest plugin allows you to simply add --memray to the command line invocation:

pytest --memray tests/

And will automatically get a report like this:

python3 -m pytest tests --memray
=============================================================================================================================== test session starts ================================================================================================================================
platform linux -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /mypackage, configfile: pytest.ini
plugins: cov-2.12.0, memray-0.1.0
collected 21 items

tests/test_package.py .....................                                                                                                                                                                                                                      [100%]


================================================================================================================================= MEMRAY REPORT ==================================================================================================================================
Allocations results for tests/test_package.py::some_test_that_allocates

	 📦 Total memory allocated: 24.4MiB
	 📏 Total allocations: 33929
	 📊 Histogram of allocation sizes: |▂   █    |
	 🥇 Biggest allocating functions:
		- parse:/opt/bb/lib/python3.8/ast.py:47 -> 3.0MiB
		- parse:/opt/bb/lib/python3.8/ast.py:47 -> 2.3MiB
		- _visit:/opt/bb/lib/python3.8/site-packages/astroid/transforms.py:62 -> 576.0KiB
		- parse:/opt/bb/lib/python3.8/ast.py:47 -> 517.6KiB
		- __init__:/opt/bb/lib/python3.8/site-packages/astroid/node_classes.py:1353 -> 512.0KiB

You can also use some of the included markers to make tests fail if the execution of said test allocates more memory than allowed:

@pytest.mark.limit_memory("24 MB")
def test_foobar():
    # do some stuff that allocates memory

To learn more on how the plugin can be used and configured check out the plugin documentation.

Native mode

Memray supports tracking native C/C++ functions as well as Python functions. This can be especially useful when profiling applications that have C extensions (such as numpy or pandas) as this gives a holistic vision of how much memory is allocated by the extension and how much is allocated by Python itself.

To activate native tracking, you need to provide the --native argument when using the run subcommand:

memray run --native my_script.py

This will automatically add native information to the result file and it will be automatically used by any reporter (such the flamegraph or table reporters). This means that instead of seeing this in the flamegraphs:

You will now be able to see what's happening inside the Python calls:

Reporters display native frames in a different color than Python frames. They can also be distinguished by looking at the file location in a frame (Python frames will generally be generated from files with a .py extension while native frames will be generated from files with extensions like .c, .cpp or .h).

Live mode

Memray output

Memray's live mode runs a script or a module in a terminal-based interface that allows you to interactively inspect its memory usage while it runs. This is useful for debugging scripts or modules that take a long time to run or that exhibit multiple complex memory patterns. You can use the --live option to run the script or module in live mode:

    memray run --live my_script.py

or if you want to execute a module:

    memray run --live -m my_module

This will show the following TUI interface in your terminal:

Sorting results

The results are displayed in descending order of total memory allocated by a function and the subfunctions called by it. You can change the ordering with the following keyboard shortcuts:

  • t (default): Sort by total memory

  • o: Sort by own memory

  • a: Sort by allocation count

The sorted column is highlighted with < > characters around the title.

Viewing different threads

By default, the live command will present the main thread of the program. You can look at different threads of the program by pressing the left and right arrow keys.

API

In addition to tracking Python processes from a CLI using memray run, it is also possible to programmatically enable tracking within a running Python program.

import memray

with memray.Tracker("output_file.bin"):
    print("Allocations will be tracked until the with block ends")

For details, see the API documentation.

License

Memray is Apache-2.0 licensed, as found in the LICENSE file.

Code of Conduct

This project has adopted a Code of Conduct. If you have any concerns about the Code, or behavior that you have experienced in the project, please contact us at opensource@bloomberg.net.

Security Policy

If you believe you have identified a security vulnerability in this project, please send an email to the project team at opensource@bloomberg.net, detailing the suspected issue and any methods you've found to reproduce it.

Please do NOT open an issue in the GitHub repository, as we'd prefer to keep vulnerability reports private until we've had an opportunity to review and address them.

Contributing

We welcome your contributions to help us improve and extend this project!

Below you will find some basic steps required to be able to contribute to the project. If you have any questions about this process or any other aspect of contributing to a Bloomberg open source project, feel free to send an email to opensource@bloomberg.net and we'll get your questions answered as quickly as we can.

Contribution Licensing

Since this project is distributed under the terms of an open source license, contributions that you make are licensed under the same terms. In order for us to be able to accept your contributions, we will need explicit confirmation from you that you are able and willing to provide them under these terms, and the mechanism we use to do this is called a Developer's Certificate of Origin (DCO). This is very similar to the process used by the Linux(R) kernel, Samba, and many other major open source projects.

To participate under these terms, all that you must do is include a line like the following as the last line of the commit message for each commit in your contribution:

Signed-Off-By: Random J. Developer <random@developer.example.org>

The simplest way to accomplish this is to add -s or --signoff to your git commit command.

You must use your real name (sorry, no pseudonyms, and no anonymous contributions).

Steps

  • Create an Issue, select 'Feature Request', and explain the proposed change.
  • Follow the guidelines in the issue template presented to you.
  • Submit the Issue.
  • Submit a Pull Request and link it to the Issue by including "#" in the Pull Request summary.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memray-1.2.0.tar.gz (938.1 kB view details)

Uploaded Source

Built Distributions

memray-1.2.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.12+ x86-64

memray-1.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl (2.5 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.12+ i686

memray-1.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

memray-1.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl (2.5 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ i686

memray-1.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

memray-1.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl (2.6 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ i686

memray-1.2.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.6 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

memray-1.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl (2.6 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ i686

File details

Details for the file memray-1.2.0.tar.gz.

File metadata

  • Download URL: memray-1.2.0.tar.gz
  • Upload date:
  • Size: 938.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.13

File hashes

Hashes for memray-1.2.0.tar.gz
Algorithm Hash digest
SHA256 0afdb04133d8a453fa5ebf56b220881b416ee9e4f48f594a77fe467be29f58cb
MD5 9b65a7f49feeba3c47850045bb54d42c
BLAKE2b-256 7e79075e6ce8e057761df865289ce4cdfde812a2ee00ee6d1ee7d2a58102adb1

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 30e524c215c77f9f8bb4157cff4b913c56713d16632e4bbb9c1237d8220b44f6
MD5 cc00803f8bfefb2e9a85b30228b26b27
BLAKE2b-256 d80dde51c03d009148b8a003b31c1bfb382e783d762a7479bedbe971df000225

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 f5ddc70070ba0869c2ace410cade4118d31dee478d2e0b45501bf8e7c721ede4
MD5 c7cab648ddef3b857d545626b6cfe2ce
BLAKE2b-256 a5e06731db101a81e6422b9d7c223259ba830345861fe25881bff3b53a7fcf96

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 3ba04ae9a3d41d1ef68c71d13a63c5b5dbdfb231d189b6b7f7e3ff281853da6e
MD5 8b1007bd3670e4ea7feaff2ca752993a
BLAKE2b-256 7e225d1e3865cb2d6ca1032fff277c07f51778684d02d690b383e9e093f8aade

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 6ad2f5858e4edde201ac4ba9e57bebb83c7dfcac4b21894dc3459f1506359a16
MD5 88df6e511a88371322a4aeb4d7609e9d
BLAKE2b-256 262b59a8f62cfb422ebb7f686d15d6c2b0a688da72055998c9ada3addf07890e

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 fced437907c77f315267598ed4d6ac2fe40e99ea550bbd9d692a07c3defdb966
MD5 aa45da1b3324842c958cc1c8ac294bc6
BLAKE2b-256 121958f86623c7ca8386887767c94c2134a3e3113eb6e67b055ebab0d7749b51

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 5b05c5cfe617e39aefbbeddc7908af387da693c7fc3e3a218ce4f8ca5c72f784
MD5 72fd870835186a3fe75669cf5cd9718a
BLAKE2b-256 c1bf90ecbe69584c35f2aeebfe357ea63f488864f3a42a1ccfa833fbf869ce5f

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 c880d71b930531dbf992940fda6103f3b9e4d4ee68e79d757be3d089420624e6
MD5 bcfaf0847dae1dd89e3a15d91eb1b607
BLAKE2b-256 b4c0d125427c9812f500f386c180156b8a953063bff54d67a6d5c0cbd942e1bd

See more details on using hashes here.

Provenance

File details

Details for the file memray-1.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for memray-1.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 55a69c25a0fa32836527efa6ede5ce836d176e5b3e8f341f3e28f7c3390bcdc8
MD5 4aecc79bce27b5aa32b2ce042d962c4f
BLAKE2b-256 96c7bd3590fa7215c255bdc590da3e1063a839004240b5b1078a0366097836b3

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page