libigl-python-bindings icon indicating copy to clipboard operation
libigl-python-bindings copied to clipboard

adjacency_list will cause memory leak.

Open kentechx opened this issue 2 years ago • 2 comments

igl.adjacency_list will produce memory leak. You can test with the following script. The garbage collector(gc) dosen't help.

import trimesh
import igl
m = trimesh.creation.icosphere()
f = np.array(m.faces)
for _ in range(10000000):
    igl.adjacency_list(f)

kentechx avatar Oct 08 '22 04:10 kentechx

This is disturbing!

It seems like this is coming from the binding itself. This similar code in C++ does not cause a memory leak:

#include <igl/adjacency_list.h>
int main()
{
  std::vector<std::vector<int> > A;
  Eigen::MatrixXi F(20,3);
  F <<
    0,11,5,
    0,5,1,
    0,1,7,
    0,7,10,
    0,10,11,
    1,5,9,
    5,11,4,
    11,10,2,
    10,7,6,
    7,1,8,
    3,9,4,
    3,4,2,
    3,2,6,
    3,6,8,
    3,8,9,
    4,9,5,
    2,4,11,
    6,2,10,
    8,6,7,
    9,8,1;
  for(int i = 0;i<100000000;i++)
  {
    igl::adjacency_list(F,A);
  }
}

Not sure the best way to go about debugging this. The good news is that it doesn't seem to be happening to all other bindings

f = np.array(m.faces)
v = np.array(m.vertices)
for _ in range(10000000):
    a = igl.cotmatrix(v,f)

doesn't appear to leak.

Maybe it has to do with numpyeigen/pybind11's treatment of the list-of-lists output from adjacency_list?

alecjacobson avatar Feb 06 '23 00:02 alecjacobson

Indeed, memory management for big objects in python is something to be improved. It appears even after removing references, GC releases allocated memory. But memory allocators might not release part of the memory to OS till the process is killed. So with your iterations, more and more memory is allocated, which leads to a collapse. Try to google some addons on better memory usage for Python processes. Or run the computation in a separate process to be sure it is killed after each iteration.

dperyel avatar Feb 08 '23 12:02 dperyel