-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Independent child process monitoring #118 #134
Changes from 1 commit
0d956a1
a846fa6
e32679b
bdf9995
aab15ed
f1cee23
099c5c8
9c62f0a
d333fda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,10 +107,10 @@ decorator function. Use as follows:: | |
del b | ||
return a | ||
|
||
If a python script with decorator ``@profile`` is called using ``-m | ||
If a python script with decorator ``@profile`` is called using ``-m | ||
memory_profiler`` in the command line, the ``precision`` parameter is ignored. | ||
|
||
Time-based memory usage | ||
Time-based memory usage | ||
========================== | ||
Sometimes it is useful to have full memory usage reports as a function of | ||
time (not line-by-line) of external processes (be it Python scripts or not). | ||
|
@@ -131,14 +131,14 @@ e.g. `mprof run -h`. | |
In the case of a Python script, using the previous command does not | ||
give you any information on which function is executed at a given | ||
time. Depending on the case, it can be difficult to identify the part | ||
of the code that is causing the highest memory usage. | ||
of the code that is causing the highest memory usage. | ||
|
||
Adding the `profile` decorator to a function and running the Python | ||
script with | ||
script with | ||
|
||
mprof run <script> | ||
|
||
will record timestamps when entering/leaving the profiled function. Runnning | ||
will record timestamps when entering/leaving the profiled function. Running | ||
|
||
mprof plot | ||
|
||
|
@@ -152,16 +152,49 @@ A discussion of these capabilities can be found `here <http://fa.bianp.net/blog/ | |
|
||
.. warning:: If your Python file imports the memory profiler `from memory_profiler import profile` these timestamps will not be recorded. Comment out the import, leave your functions decorated, and re-run. | ||
|
||
The available commands for `mprof` are: | ||
The available commands for `mprof` are: | ||
|
||
- ``mprof run``: running an executable, recording memory usage | ||
- ``mprof run``: running an executable, recording memory usage | ||
- ``mprof plot``: plotting one the recorded memory usage (by default, | ||
the last one) | ||
- ``mprof list``: listing all recorded memory usage files in a | ||
user-friendly way. | ||
- ``mprof clean``: removing all recorded memory usage files. | ||
- ``mprof rm``: removing specific recorded memory usage files | ||
|
||
Tracking forked child processes | ||
=============================== | ||
In a multiprocessing context the main process will spawn child processes whose | ||
system resources are allocated separately from the parent process. This can | ||
lead to an inaccurate report of memory usage since by default only the parent | ||
process is being tracked. The ``mprof`` utility provides two mechanisms to | ||
track the usage of child processes: sum the memory of all children to the | ||
parent's usage and track each child individual. | ||
|
||
To create a report that combines memory usage of all the children and the | ||
parent, use the ``include_children`` flag in either the ``profile`` decorator or | ||
ass a command line argument to ``mprof``:: | ||
|
||
mprof run --include-children <script> | ||
|
||
The second method tracks each child independently of the main process, | ||
serializing child rows by index to the output stream. Use the ``multiprocess`` | ||
flag and plot as follows:: | ||
|
||
mprof run --multiprocess <script> | ||
mprof plot | ||
|
||
This will create a plot using matplotlib similar to this: | ||
|
||
.. image:: https://cloud.githubusercontent.com/assets/745966/24075879/2e85b43a-0bfa-11e7-8dfe-654320dbd2ce.png | ||
: target: https://github.com/fabianp/memory_profiler/pull/134 | ||
: height: 350px | ||
|
||
You can combine both the ``include_children`` and ``multiprocess`` flags to show | ||
the total memory of the program as well as each child individually. | ||
|
||
.. warning:: currently the child tracking only works if a ``stream`` is provided to the ``profile`` (e.g. from the command line or in the decorator). | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am confused, as the example works fine even without decorated functions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant that the stream argument has to be passed in, if Perhaps I could rephrase as follows: "Currently tracking individual children requires a reporting output stream; if you'd like direct access to the memory usage of individual children, see the Though of course, that then points the user to an internal function. I'm open to suggestions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've put placeholder comments in the code (line 363 and 403) where this issue occurs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, thanks for the explanation. I think the API would be simpler if we allow memory_usage to return a nested list instead embedding this into the stream. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I've updated |
||
Setting debugger breakpoints | ||
============================= | ||
It is possible to set breakpoints depending on the amount of memory used. | ||
|
@@ -260,7 +293,7 @@ LogFile of memory profiler module. | |
>>> import sys | ||
>>> sys.stdout = LogFile('memory_profile_log') | ||
|
||
``Customised reporting:`` | ||
``Customized reporting:`` | ||
|
||
Sending everything to the log file while running the memory_profiler | ||
could be cumbersome and one can choose only entries with increments | ||
|
@@ -412,6 +445,8 @@ cleanup. | |
|
||
`Dmitriy Novozhilov <https://github.com/demiurg906>`_ and `Sergei Lebedev <https://github.com/superbobry>`_ added support for `tracemalloc <https://docs.python.org/3/library/tracemalloc.html>`_. | ||
|
||
`Benjamin Bengfort <https://github.com/bbengfort>`_ added support for tracking the usage of individual child processes and plotting them. | ||
|
||
========= | ||
License | ||
========= | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How hard do you think it would be to remove this limitation?, i.e., to track children even if the function is not @Profile'd