Skip to content

Commit

Permalink
Port the tree reporter to textual
Browse files Browse the repository at this point in the history
Now that we are using Textual for the live mode, we can port the tree
reporter to be a live Textual App. This has plenty of advantages over
the static version as it offers interactive exploration of the tree, as
well as the possibility of using different screens for showing detailed
information about allocations such as the source and metadata.

Signed-off-by: Pablo Galindo <[email protected]>
  • Loading branch information
pablogsal committed Nov 30, 2023
1 parent 3f0447b commit 793cfe4
Show file tree
Hide file tree
Showing 12 changed files with 5,035 additions and 1,260 deletions.
Binary file modified docs/_static/images/tree_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 20 additions & 9 deletions docs/tree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ the tracked process at the time when its memory usage was at its peak.

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

The tree reporter shows some statistics followed by a tree representation of
the allocated memory. Several aspects are important when interpreting the tree
representation:
The tree reporter shows an interactive terminal applocation 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
displayed. This is configurable with the ``--biggest-allocs`` command line
Expand All @@ -17,17 +17,28 @@ representation:
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.
* Call chains of one node are collapsed for better readability. This means that
branches in the tree where each node has only one child are collapsed and a
special node is shown to reflect this. The hidden frames **never** correspond
to frames that contained one of the source locations with the biggest
allocations. The hidden frames are always callers of functions where the reported
allocation happened.
* 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.
* Frames are colored based on their reported memory usage percentage, from red
(most bytes allocated) to green (fewest).
* You can interact with the application using the following keys:

* You can navigate the tree using the arrow keys. Pressing the up arrow key
will move up one level in the tree, while pressing the down arrow key will
move down one row. When a new row is selected, the panel on the right
will be updated to show the source code of the selected frame and some metadata
about the allocations made by that frame and its children.
* Pressing the 'e' key will expand nodes and their children recursively until a node with
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".

.. note::
If the ``textual[syntax]`` package is installed, the Python source files
will be displayed with syntax highlighting!


Basic Usage
-----------
Expand Down
1 change: 1 addition & 0 deletions news/499.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Port the tree reporter to be an interactive Textual App.
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ ipython
setuptools; python_version >= '3.12'
pkgconfig
pytest-textual-snapshot
textual >= '0.43'
13 changes: 0 additions & 13 deletions src/memray/commands/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
from pathlib import Path
from textwrap import dedent

from rich import print as rprint

from memray import FileReader
from memray._errors import MemrayCommandError
from memray._memray import size_fmt
from memray.commands.common import warn_if_not_enough_symbols
from memray.reporters.tree import TreeReporter

Expand Down Expand Up @@ -80,14 +77,4 @@ def run(self, args: argparse.Namespace, parser: argparse.ArgumentParser) -> None
f"Failed to parse allocation records in {result_path}\nReason: {e}",
exit_code=1,
)
print()
header = "Allocation metadata"
rprint(f"{header}\n{'-'*len(header)}")
rprint(f"Command line arguments: '{reader.metadata.command_line}'")
rprint(f"Peak memory size: {size_fmt(reader.metadata.peak_memory)}")
rprint(f"Number of allocations: {reader.metadata.total_allocations}")
print()
header = f"Biggest {args.biggest_allocs} allocations:"
rprint(header)
rprint("-" * len(header))
reporter.render()
Loading

0 comments on commit 793cfe4

Please sign in to comment.