Profiling memory usage in Python is important for identifying memory leaks and optimizing your code’s memory efficiency.
Profiling memory usage in Python can be done using various tools and techniques. Here are some common methods to profile memory usage in Python:
1. Memory Profilers:
To profile memory usage in a Python program, you can use the memory_profiler
library. This library allows you to monitor memory usage line-by-line in your code. Here’s how you can use it:
- Install
memory_profiler
:
You can install memory_profiler
using pip:
pip install memory-profiler
Code language: Python (python)
- Create a Python script you want to profile, e.g.,
my_script.py
. - Add memory profiling to your script:
# my_script.py
from memory_profiler import profile
@profile
def my_function():
a = [1] * (10 ** 6) # Create a large list
b = [2] * (2 * 10 ** 7) # Create an even larger list
del b # Delete the large list to free memory
return a
if __name__ == "__main__":
my_function()
Code language: Python (python)
In the code above, we’ve imported the profile
decorator from memory_profiler
and applied it to the my_function
function. This decorator will profile the memory usage of the function when it’s called.
- Run the memory profiler:
Open a terminal and run the script using the mprof
command-line tool that comes with memory_profiler
. You can use the mprof
tool to start, stop, and view memory usage statistics.
To start profiling, run:
mprof run my_script.py
Code language: Python (python)
To profile memory usage in a Python program, you can use the memory_profiler
library. This library allows
- Analyze the results:
After running the script, you can analyze the memory usage profile by running:
mprof plot
Code language: Python (python)
This command will generate a plot showing memory usage over time. You can also use other mprof
commands to inspect the memory usage data.
Keep in mind that memory_profiler
adds some overhead to your code, so it’s best used for profiling memory-intensive parts of your application rather than for overall performance monitoring.
Remember to remove the @profile
decorator and any profiling code before deploying your application to production because it’s meant for debugging and development purposes only.
Example of what the output might look like:
The output of the memory_profiler
tool will show you a line-by-line breakdown of memory usage as your Python script runs. Here’s an example of what the output might look like when you run a script with memory profiling:
Line # Mem usage Increment Line Contents
================================================
4 32.547 MiB 0.000 MiB @profile
5 def my_function():
6 32.547 MiB 0.000 MiB a = [1] * (10 ** 6) # Create a large list
7 162.051 MiB 129.504 MiB b = [2] * (2 * 10 ** 7) # Create an even larger list
8 32.547 MiB -129.504 MiB del b # Delete the large list to free memory
9 32.547 MiB 0.000 MiB return a
Code language: Python (python)
In this example, the output provides information for each line of code in the my_function
function:
Line #
: The line number in the script where the memory usage is being measured.Mem usage
: The total memory usage at that line.Increment
: The change in memory usage compared to the previous line.Line Contents
: The actual code at that line.
Here’s an explanation of the output:
- Line 6: Memory usage increases as the
a
list is created. - Line 7: Memory usage increases significantly as the
b
list is created. - Line 8: Memory usage decreases as the
b
list is deleted. - Line 9: Memory usage remains the same as it returns the
a
list.
The Increment
column shows how much memory is allocated or deallocated at each line. In this example, you can see that the largest memory increase happens on Line 7 when the large b
list is created.
This information helps you identify which parts of your code are responsible for increased memory usage, making it easier to optimize memory-intensive sections of your Python script.
2. Using Resource Module:
You can use Python’s built-in resource
module to profile memory usage. It’s not as detailed as some third-party tools, but it can provide basic information. Here’s an example of how to use it:
The resource
module in Python can be used to profile memory usage, but it’s relatively basic compared to more specialized memory profiling tools. It provides information about resource usage by the current process, including memory usage. Here’s a detailed example of how to use the resource
module to profile memory usage:
import resource
import time
def profile_memory_usage():
# Start tracking resource usage
resource_usage_start = resource.getrusage(resource.RUSAGE_SELF)
# Code you want to profile goes here
numbers = []
for i in range(1, 10001):
numbers.append(i)
# Stop tracking resource usage
resource_usage_end = resource.getrusage(resource.RUSAGE_SELF)
# Calculate memory usage
memory_usage = resource_usage_end.ru_maxrss - resource_usage_start.ru_maxrss
# Memory usage is in kilobytes, so convert it to megabytes
memory_usage_mb = memory_usage / 1024
print(f"Memory Usage: {memory_usage_mb:.2f} MB")
if __name__ == "__main__":
profile_memory_usage()
Code language: Python (python)
In this example:
- We import the
resource
module, which allows us to track resource usage. - The
profile_memory_usage
function is defined. - We start tracking resource usage using
resource.getrusage(resource.RUSAGE_SELF)
to get resource usage statistics before running the code you want to profile. - In the code section you want to profile (in this case, creating a list of numbers), you should replace this with the part of your application you want to profile.
- After executing the code you want to profile, we stop tracking resource usage again using
resource.getrusage(resource.RUSAGE_SELF)
to get resource usage statistics after running the code. - We calculate memory usage by subtracting the maximum resident set size (RSS) before and after running the code.
- We convert the memory usage from kilobytes to megabytes for a more readable output.
- Finally, we print the memory usage in megabytes.
When you run this script, it will output the memory usage of the code section you profiled. Keep in mind that the resource
module provides basic information about resource usage, and more specialized memory profiling tools may offer more detailed insights into your program’s memory usage.
3. Using Tracemalloc
tracemalloc
is a Python module that allows you to trace memory allocations in your code. It’s available in Python 3.4 and later versions. Here’s a detailed example of how to use tracemalloc
to profile memory usage:
import tracemalloc
# Function to profile memory usage
def profile_memory_usage():
tracemalloc.start() # Start tracing memory allocations
# Code you want to profile goes here
numbers = []
for i in range(1, 10001):
numbers.append(i)
# Take a snapshot of memory usage
snapshot = tracemalloc.take_snapshot()
print("Top 10 Memory Consuming Lines:")
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
# Stop tracing memory allocations
tracemalloc.stop()
if __name__ == "__main__":
profile_memory_usage()
Code language: Python (python)
In this example:
- We import the
tracemalloc
module. - The
profile_memory_usage
function is defined, and we start tracing memory allocations usingtracemalloc.start()
. - In the code section you want to profile, we create a list of numbers. This is just an example; you should replace this code with the part of your application that you want to profile.
- After executing the code you want to profile, we take a snapshot of memory usage using
tracemalloc.take_snapshot()
. - We then print the top 10 memory-consuming lines using
snapshot.statistics('lineno')
. This provides information about which lines in your code are consuming the most memory. - Finally, we stop tracing memory allocations using
tracemalloc.stop()
.
When you run this script, it will output information about the top memory-consuming lines in the code section you profiled. This can help you identify areas in your code that may need optimization or where memory is being used inefficiently.
4. Using Psutil
ou can also use the psutil
library to profile memory usage in Python. psutil
is a cross-platform library for accessing system details and managing processes. Here’s how you can use psutil
to profile memory usage:
- First, make sure you have
psutil
installed. You can install it usingpip
:
pip install psutil
Code language: Python (python)
- Next, you can use psutil to profile memory usage in your Python script. Here’s an example:
import psutil
def profile_memory_usage():
process = psutil.Process()
memory_info = process.memory_info()
print(f"Memory Usage (RSS): {memory_info.rss / (1024 * 1024)} MB")
print(f"Memory Usage (Virtual): {memory_info.vms / (1024 * 1024)} MB")
if __name__ == "__main__":
profile_memory_usage()
Code language: Python (python)
psutil.Process()
is used to get information about the current process.memory_info.rss
provides the resident set size (RSS) memory usage in bytes.memory_info.vms
provides the virtual memory size (VMS) memory usage in bytes.
This example prints the memory usage in megabytes (MB). You can adjust the output format and customize it according to your needs.
Remember that psutil
provides a wide range of system-related information and can be a powerful tool for profiling and monitoring your Python applications.
5. Using Guppy
You can use the guppy
library (specifically, guppy3
) to profile memory usage in Python. guppy
is a third-party library that provides memory profiling capabilities. It’s particularly useful for analyzing memory usage and finding memory leaks in your Python code.
Here’s an example of how to use guppy3
to profile memory usage:
- First, you need to install the
guppy3
library usingpip
:
pip install guppy3
Code language: Python (python)
- Next, you can use
guppy3
in your Python script. Here’s an example:
from guppy import hpy
def profile_memory_usage():
hp = hpy()
h = hp.heap()
# Code you want to profile goes here
numbers = []
for i in range(1, 10001):
numbers.append(i)
# Analyze memory usage
memory_info = h.byrcs
for rc in memory_info:
print(f"Type: {rc}")
print(f"Count: {memory_info[rc].count}")
print(f"Size (bytes): {memory_info[rc].size}\n")
if __name__ == "__main__":
profile_memory_usage()
Code language: Python (python)
In this example:
- We import
hpy
from theguppy
module to create a heap profiler. - Inside the
profile_memory_usage
function, we create an instance of the heap profiler usinghpy()
, and then we obtain a heap snapshot usinghp.heap()
. - The code section you want to profile is represented by the creation of a list of numbers. You should replace this code with the part of your application that you want to profile.
- After executing the code, we use
h.byrcs
to analyze memory usage by type. This provides information about the types of objects in memory, the count of instances, and their sizes. - Finally, we print the memory usage information.
guppy3
can provide detailed insights into your program’s memory usage, making it useful for debugging memory-related issues and optimizing memory usage in your Python code.
6. Using objgraph Module
objgraph
module in Python to visualize and analyze the object reference graph, which can be helpful for identifying memory usage and potential memory leaks in your Python code. Here’s how you can use the objgraph
module:
- Install
objgraph
usingpip
:
pip install objgraph
Code language: Python (python)
- Import the
objgraph
module in your Python script:
import objgraph
Code language: Python (python)
- Create a function or a section of your code that you want to profile for memory usage:
def profile_memory_usage():
# Code you want to profile goes here
numbers = []
for i in range(1, 10001):
numbers.append(i)
Code language: Python (python)
- Within your profiling function, you can use
objgraph
to visualize object references and identify memory usage:
def profile_memory_usage():
# Code you want to profile goes here
numbers = []
for i in range(1, 10001):
numbers.append(i)
# Visualize object references
objgraph.show_most_common_types(limit=10)
Code language: Python (python)
The show_most_common_types
function will print the most common types of objects in memory, which can help you identify potential memory usage issues.
- Call your profiling function to analyze memory usage:
if __name__ == "__main__":
profile_memory_usage()
Code language: Python (python)
When you run this script, it will display information about the most common types of objects in memory. This information can be valuable for identifying objects that are consuming a significant amount of memory and for debugging memory-related issues.
Keep in mind that objgraph
is primarily used for visualization and analysis of object references, so it complements other memory profiling tools like tracemalloc
or guppy
that provide more detailed memory usage statistics.
7. Using sys.getsizeof():
This built-in Python function allows you to measure the size of individual objects in memory. It’s useful for checking the memory consumption of specific variables or objects.
import sys
my_variable = [1, 2, 3, 4, 5]
print(sys.getsizeof(my_variable))
Code language: Python (python)
8. Using Heapy
This is a Python library that provides a way to profile and inspect memory usage. It’s particularly helpful for diagnosing memory leaks.
Install Heapy:
pip install guppy3
Code language: Python (python)
Example usage:
from guppy import hpy
hp = hpy()
heap = hp.heap()
print(heap)
Code language: Python (python)
9. External Tools:
You can also use external memory profiling tools like Valgrind’s Massif or Pyflame for more in-depth analysis, but these tools are not Python-specific.
Remember that profiling memory usage can have an impact on the performance of your code, so use these tools judiciously, especially in production environments. Additionally, interpreting memory profiling results requires a good understanding of Python’s memory management and the specifics of your code.
Read More;
- Python cProfile to CSV With Example
- Python Profile to File With Examples
- CProfileV: Making Python cProfile Usage Effortless
- Python cProfile Vs Timeit
- Python cProfile tottime vs cumtime
- Python cProfile With Arguments [With Example]
- Profile a Jupyter Notebook in Python
- Python cProfile Not Working [Solutions]
- Python cProfile Name is Not Defined (Fixed)
- Python cProfile ncalls With Examples
- Python cProfile Limit Depth
- Python cProfile to HTML With Example