Background: The 2 AM OOM Killer Nightmare
Imagine you’re running a Python data processing system. Everything is stable until the record count hits 100,000. At exactly 2 AM, your phone rings: the server has crashed. Checking the logs, you see the haunting words: Out of Memory (OOM) Killer.
The OS took it upon itself to “execute” the application because it devoured 16GB of RAM in minutes. At this point, tools like top or psutil only tell you that RAM is increasing; they are powerless to pinpoint the specific line of code or object hogging the memory. After hours of struggling, I found Memray. This tool is a true game-changer.
Why do legacy tools often disappoint?
In the past, memory_profiler was the go-to choice. However, it slows down programs by 10 to 50 times. Its fatal flaw is the inability to see memory consumed by C extensions like NumPy, Pandas, or database drivers. Meanwhile, Memray is written in C++, allowing it to track both Python and native code with extremely low overhead.
Installing Memray in a Flash
Memray is an open-source product from Bloomberg. It works best on Linux. If you’re on macOS, you might face some feature limitations. Windows users can run it smoothly via WSL2.
pip install memray
For strict production environments, ensure you have python3-dev installed. This prevents compilation errors for extension components midway through.
Profiling Code Without “Polluting” the Project
What I love most is that Memray doesn’t force you to modify your source code. You don’t need to insert decorators or add import statements to your production files. Everything is handled externally.
1. Running a Basic Profile
Suppose you need to check processor.py. Simply execute the following command:
python3 -m memray run processor.py
Memray will generate a binary file containing the full memory allocation history. The filename usually follows the format memray-processor.py.<pid>.bin.
2. Reading the Flamegraph Report
Binary data is difficult to read with the naked eye. Convert it into a visual HTML format using the following command:
python3 -m memray flamegraph memray-processor.py.<pid>.bin
Open the generated HTML file in your browser, and you’ll see a memory allocation map. The wider the blocks, the more RAM that function consumes. You can click directly on each block to see the exact line of code causing the waste.
In Practice: Hunting Down “Hidden” RAM Hogs
Consider a real-world example: a log processing script leaking memory because it stores data in a global list without clearing it.
# leak_example.py
import time
def process_data():
# Simulate data accumulation causing a leak
cache = []
for i in range(10000):
cache.append(f"Record_{i}" * 100)
return len(cache)
if __name__ == "__main__":
for _ in range(10):
process_data()
time.sleep(0.5)
Instead of waiting for the script to finish, you can use the --live feature to observe it immediately:
python3 -m memray run --live leak_example.py
A professional terminal interface will appear, listing the functions consuming the most RAM in real-time. You’ll immediately see the process_data function continuously driving up memory usage without it ever dropping.
Deep Analysis with Table View
If the Flamegraph makes your head spin, try the Table view:
python3 -m memray table memray-leak_example.py.<pid>.bin
This table provides three key metrics: Total Memory, Own Memory, and Allocation Count. Experience shows that sometimes the Allocation Count is more important than the total size. Creating millions of small objects creates significant overhead for Python to manage, slowing down the system considerably.
Real-world Memory Optimization Tips
After handling many tough OOM cases, I’ve distilled three golden rules for using Memray:
- Always enable Native mode: Use the
--nativeflag when working with Pandas or Machine Learning. Without it, you’ll miss the massive chunk of memory residing in the C/C++ layer.python3 -m memray run --native script.py - Hunt for Peak Memory: Sometimes RAM doesn’t increase continuously (leak) but spikes (peak) and then drops. Memray helps you identify peak moments so you can replace a
list comprehensionwith agenerator, potentially reducing RAM from several GBs to just a few MBs. - Save snapshots: Keep report files from before and after optimization. The feeling of watching the RAM chart shrink after a code fix is incredibly satisfying and serves as the best proof of your work’s impact.
Memray is more than just a debugging tool. It helps you understand how Python operates under the hood. If your project is consuming an unusual amount of RAM, install Memray today. Wishing you peaceful nights of sleep, free from OOM Killer worries!

