On Fri, Jul 18, 2008 at 12:03 PM, Charles R Harris <charlesr.harris@gmail.com> wrote:
<snip>


Simpler test case:

import sys, gc
import numpy as np

def main() :
    t = np.dtype(np.float32)
    print sys.getrefcount(t)
    for i in range(100) :
        np.float32()
        gc.collect()
    print sys.getrefcount(t)

if __name__ == "__main__" :
    main()

Result

$[charris@f8 ~]$ python debug.py
5
105

So there is a leak. The question is the proper fix. I want to take a closer look at PyArray_Return and also float32() and relations.

The reference leak seems specific to the float32 and complex64 types called with default arguments.

In [1]: import sys, gc

In [2]: t = float32

In [3]: sys.getrefcount(dtype(t))
Out[3]: 4

In [4]: for i in range(10) : t();
   ...:

In [5]: sys.getrefcount(dtype(t))
Out[5]: 14

In [6]: for i in range(10) : t(0);
   ...:

In [7]: sys.getrefcount(dtype(t))
Out[7]: 14

In [8]: t = complex64

In [9]: sys.getrefcount(dtype(t))
Out[9]: 4

In [10]: for i in range(10) : t();
   ....:

In [11]: sys.getrefcount(dtype(t))
Out[11]: 14

In [12]: t = float64

In [13]: sys.getrefcount(dtype(t))
Out[13]: 19

In [14]: for i in range(10) : t();
   ....:

In [15]: sys.getrefcount(dtype(t))
Out[15]: 19
 
This shouldn't actually leak any memory as these types are singletons, but it points up a logic flaw somewhere.

Chuck