Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ packaging tools. We recommend installing the latest stable release from

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 or macOS), you'll need to ensure that all the dependencies are satisfied on the
(Linux i686, x86-64, or aarch64, or macOS), you'll need to ensure that all the dependencies are satisfied on the
system where you are doing the installation.

## Building from source
Expand All @@ -93,11 +93,18 @@ before installing `memray`. Check the documentation of your package manager to k
files for more detailed information.

If you are building on MacOS, you will also need to set the deployment target.
On Intel Macs:

```shell
export MACOSX_DEPLOYMENT_TARGET=10.14
```

On Apple Silicon Macs:

```shell
export MACOSX_DEPLOYMENT_TARGET=11.0
```

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

```shell
Expand Down Expand Up @@ -128,7 +135,8 @@ You can find the latest documentation available [here](https://bloomberg.github.
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} ...
usage: memray [-h] [-v] [-V]
{run,flamegraph,table,live,tree,parse,summary,stats,transform,attach,detach} ...

Memory profiler for Python applications

Expand All @@ -141,7 +149,7 @@ Example:
$ python3 -m memray flamegraph output.bin

positional arguments:
{run,flamegraph,table,live,tree,parse,summary,stats}
{run,flamegraph,table,live,tree,parse,summary,stats,transform,attach,detach}
Mode of operation
run Run the specified application and track memory usage
flamegraph Generate an HTML flame graph for peak memory usage
Expand All @@ -151,13 +159,17 @@ positional arguments:
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
transform Generate reports files in different formats
attach Begin tracking allocations in an already-started process
detach End the tracking started by a previous ``memray attach`` call

optional arguments:
-h, --help Show this help message and exit
options:
-h, --help show this help message and exit
-v, --verbose Increase verbosity. Option is additive and can be specified up to 3 times
-V, --version Displays the current version of Memray

Please submit feedback, ideas, and bug reports by filing a new issue at https://github.com/bloomberg/memray/issues
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:
Expand All @@ -179,10 +191,10 @@ 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:
The output will be a binary file (like `memray-my_script.py.2369.bin`) that you can analyze in different ways. One way is to use the `memray flamegraph` command to generate a flame graph:

```shell
memray flamegraph my_script.2369.bin
memray flamegraph memray-my_script.py.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:
Expand Down Expand Up @@ -292,7 +304,7 @@ The sorted column's heading is underlined.

## 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 greater than and less than keys, `<` and `>`. In most terminals you can also click the "Previous Thread" and "Next Thread" buttons on the footer.
By default, the live command will present allocations from all of the program's threads. You can look at individual threads of the program by first pressing `m` (to disable thread merging), and then pressing the greater than and less than keys, `<` and `>`, to switch between threads. In most terminals you can also click the "Unmerge Threads", "Previous Thread", and "Next Thread" buttons on the footer.

<img src="https://github.com/bloomberg/memray/blob/main/docs/_static/images/live_different_thread.png?raw=true" align="center"/>

Expand Down
24 changes: 12 additions & 12 deletions docs/attach.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ first TUI session.
Debugger Privileges
-------------------

Memray leverages a debugger for attaching to the process. It is compatible with
both gdb and lldb, but one or the other must be installed in order for ``memray
attach`` to work. Only a super user (either root, or a user with the
``CAP_SYS_PTRACE`` capability) can attach to processes run by another user.
When run with Python 3.14 or newer, Memray uses :func:`sys.remote_exec` for
attaching to the process by default, which requires the process to run the
same major and minor Python version. Otherwise, it leverages a debugger. It is
compatible with both gdb and lldb, but one or the other must be installed in
order to attach with a debugger. The ``--method`` option selects a specific
method, such as a debugger for a process running a different Python version.
Only a super user (either root, or a user with the ``CAP_SYS_PTRACE``
capability) can attach to processes run by another user.
Further, security settings on modern Linux systems typically prevent a regular
user from attaching even to their own processes. You can loosen that
restriction by writing ``0`` to ``/proc/sys/kernel/yama/ptrace_scope`` as root,
Expand Down Expand Up @@ -87,14 +91,10 @@ you're attempting to attach to, depending on what it's doing at the point when
we attach. We advise only using this as a debugging tool on development
machines.

If you attach to a Python 3.7 or Python 3.8 process that has never imported the
``threading`` module, the attached process will show an error when the
interpreter finishes running the main script. This is due to `a known bug
<https://github.com/python/cpython/issues/81597>`_ that was not fixed until
Python 3.9. From Python 3.9 onwards there will be no error on exit, but the
interpreter will assign the wrong name to the main thread if ``threading`` is
later imported by the script. That should not have any major effect on the
behavior of the program.
If you attach to a Python 3.12 or older process that has never imported the
``threading`` module, the interpreter will assign the wrong name to the main
thread if ``threading`` is later imported by the script. That should not have
any major effect on the behavior of the program.

When attaching to a running process, Memray will ``import`` a helper module.
This means that Memray must be installed in the Python environment that the
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The projects in the directories located here contain very simple
examples to demonstrate usage with Memray.

Make sure you install the required dependencies by running
``python3.9 -m pip install -r requirements.txt`` in the respective
``python3 -m pip install -r requirements.txt`` in the respective
directory. The examples below use the project in the ``mandelbrot`` folder, but
you can use the same instructions to launch the other examples as well.

Expand Down
6 changes: 3 additions & 3 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ PyPI

When installing Memray with ``pip`` you need to install it with the
Python interpreter you intend to run your profiled application with. In
this case example we're installing it for use with Python 3.9:
this example we're installing it for use with ``python3``:

.. code:: shell

python3.9 -m pip install memray
python3 -m pip install memray

Using the CLI
-------------
Expand All @@ -24,7 +24,7 @@ You can invoke Memray the following way:

.. code:: shell

python3.9 -m memray
python3 -m memray

Or alternatively through the ``memray`` script:

Expand Down
2 changes: 1 addition & 1 deletion docs/live.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ To use live mode, you can specify the program to be profiled in live mode using
$ memray run --live application.py

Immediately Memray will start your process in the background and will connect a TUI to it in the foreground. The TUI will
display the current high watermark of the heap every time it takes a snapshot, in a tabular format.
display the heap's current allocations every time it takes a snapshot, in a tabular format.

.. image:: _static/images/live_running.png

Expand Down
2 changes: 1 addition & 1 deletion docs/run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ especially when tracking down memory leaks.

.. note::
This acts also as an alternative way to run with ``PYTHONMALLOC=malloc`` but
in a way that allows distiguishing allocations made by using the system
in a way that allows distinguishing allocations made by using the system
allocator directly and ones made by using the Python allocator.

.. code:: shell
Expand Down
17 changes: 9 additions & 8 deletions docs/supported_environments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ Only CPython is supported.
Supported Python versions
-------------------------

Every Python version that hasn't reached end of life is supported.
Every Python version that hasn't reached end of life is supported, and older
versions may remain supported for a while.

Currently that's Python 3.8 through 3.14.
Currently that's Python 3.9 through 3.15.

Supported operating systems
---------------------------

You will have the best Memray experience on Linux.

We also support macOS 11 or newer. We cannot support older
macOS versions, as they don't provide a C++17 compatible runtime. Although all
We also support macOS 10.14 or newer on Intel Macs, and macOS 11 or newer on
Apple Silicon Macs. We cannot support older macOS versions, as they don't
provide a C++17 compatible runtime. Although all
features work on macOS, the way that macOS applications and Python libraries
are typically distributed often results in subpar native stacks on Mac. See
:ref:`the native mode documentation <mac symbolification>` for details on these
Expand All @@ -37,14 +39,13 @@ For Linux, we test on ``i686``, ``x86-64``, and ``aarch64``. Pre-built wheels
are available on PyPI.

For macOS, we test on ``x86-64`` and ``arm64`` - so, both Intel and Apple
Silicon Macs. Pre-built wheels are available for both architectures, though
only for Python 3.8 and newer.
Silicon Macs. Pre-built wheels are available for both architectures.

Supported runtime environments
------------------------------

We require a C++17 runtime. As noted above, macOS 11 or higher is required for
a C++17 runtime on Mac.
We require a C++17 runtime. As noted above, macOS 10.14 or higher is required
for a C++17 runtime on Mac.

On Linux we support glibc and musl libc. Other libc's have not been tested, and
issues are likely. We support platforms compatible with the ``manylinux2014``
Expand Down
11 changes: 10 additions & 1 deletion docs/transform.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,21 @@ The available columns are:
* ``size``: the total size in bytes of the allocations performed at this
location by this thread and not deallocated before the high water mark.
* ``tid``: the thread id of the thread that performed the allocations.
* ``thread_name``: the name of the thread that performed the allocations.
* ``thread_name``: that thread's id and name, such as ``0x3 (worker)``.
* ``stack_trace``: the stack trace of the allocations. The stack trace is
represented as a ``|`` separated list of stack frames (most recent call
first), where each stack frame in the list has the following format:
``<function_name>;<file_name>;<line_number>``.

speedscope
~~~~~~~~~~

This format allows you to produce JSON files that can be opened with
`speedscope <https://www.speedscope.app>`_. By default, the file contains two
profiles of the allocations that contributed to the process's memory high water
mark: one weighted by allocated bytes and one weighted by number of
allocations.

CLI Reference
-------------

Expand Down
16 changes: 6 additions & 10 deletions docs/tree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ the tracked process at the time when its memory usage was at its peak.

.. image:: _static/images/tree_example.png

The tree reporter shows an interactive terminal applocation displaying a tree
The tree reporter shows an interactive terminal application displaying a tree
representation of the allocated memory. Several aspects are important when
interpreting the tree representation:

* Only the 10 source locations responsible for the most allocated bytes are
* Only the 200 source locations responsible for the most allocated bytes are
displayed. This is configurable with the ``--biggest-allocs`` command line
parameter.
* The total memory and percentage shown in the root node of the tree are
calculated based only on the allocations that are shown. Since any allocation
not big enough to be shown will not be included there, the reported total
memory of the root node is normally less than the process's peak memory size.
* The total memory shown in the root node of the tree includes the allocations
that are not big enough to be shown. Those are summarized together in a
separate node under the root.
* The "📂" icon represents a frame that is a **caller** of a function where an
allocation happened while the "📄" icon represents a frame that allocated
memory.
Expand All @@ -33,7 +32,7 @@ interpreting the tree representation:
more than one child is found. This can be used to quickly expand the tree.
* Pressing the 'i' key will hide all nodes that belong to the import system and their
children.
* Presing the 'u' key will show all nodes that are marked as "uninteresting".
* Pressing the 'u' key will show all nodes that are marked as "uninteresting".

.. note::
If the ``textual[syntax]`` package is installed, the Python source files
Expand All @@ -52,9 +51,6 @@ The general form of the ``tree`` subcommand is:
The only argument the ``tree`` subcommand requires is the capture file
previously generated using :doc:`the run subcommand <run>`.

The output will be printed directly to standard output. If standard output is
a terminal, the output will be colorized.

CLI Reference
-------------

Expand Down
2 changes: 1 addition & 1 deletion src/memray/commands/_parse_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def prepare_run_parser(parser: argparse.ArgumentParser) -> None:
output_group.add_argument(
"-o",
"--output",
help="Output file name (default: <process_name>.<pid>.bin)",
help="Output file name (default: memray-<script>.<pid>.bin)",
)
output_group.add_argument(
"--live",
Expand Down
Loading