0

I have a Rust library using PyO3, and one of my functions looks like this:

#[pyfunction]
pub fn my_func<'a>(py: Python<'a>) -> PyResult<&'a PyBytes> {
    let my_data: Vec<u8> = do_stuff(); // very large data here, >1GB
    let result = PyBytes::new(py, &my_data[..]);
    println!("Returning {} bytes to Python", my_data.len());
    Ok(result)
}

From Python, I can successfully get my data:

import MyLibrary
result : bytes = MyLibrary.my_func()

I've found that the first time I call this, it works fine. The second time I call it, my library prints out the message then fails, giving me something like memory allocation of 1073741824 bytes failed -- meaning the failure is occurring in the passing of memory between them.

If I run two of these calls sequentially, I see that my RAM utilization is about 11 GiB after the first call; it spikes to >16 GiB before failing on the second call. Right now, I'm doing some testing in which I don't actually use the return data and simply overwrite it; basically:

for i in range(10):
    result = MyLibrary.my_func()
    print(len(result))

It seems that my data are allocated in Rust, returned to Python, then not freed. Is there something I can do (either in Rust or Python) to make sure that the memory gets freed?

user655321
  • 1,572
  • 2
  • 16
  • 33
  • It seems like Python's garbage collector just hasn't gotten around to freeing it yet. You could possibly integrate it with the [`with` statement API](https://www.python.org/dev/peps/pep-0343/) for custom cleanup behavior, or just run `import gc; gc.collect()` after setting `result` to some other value like `None` from Python to force a GC pass. – Aplet123 Jan 29 '21 at 02:14
  • This appears to help insofar as it completes the second call, but it fails on the third round just the same. RAM usage (I'm running within WSL2) starts a little over 1GB for the VM and peaks at 16GB at the end of the first pass. It drops to about 7.5GB when starting the second, hitting 16GB again after 2. Drops down before crashing towards the end of the third. – user655321 Jan 29 '21 at 02:40

0 Answers0