Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quiver leaks memory when called multiple times #2556

Closed
markdbenedict opened this issue Oct 28, 2013 · 2 comments
Closed

Quiver leaks memory when called multiple times #2556

markdbenedict opened this issue Oct 28, 2013 · 2 comments

Comments

@markdbenedict
Copy link

I have created quite a nice visualization program using Qt as the interface layer and matplotlib to draw much of the content. I use contour and countourf as well as text and lines and never run into problems with releasing objects. I need to draw many plots to create the input for an animation.

As soon as I start calling Axes.quiver I get leaks. With the size of the dataset it adds up quickly. I am unable to use the animation module due to conflicts with other functionality, and the X,Y values and shapes change between frames so quiver.set_UVC() is of no use to me.

The following code demonstrates the problem with the simple for loop replacing the animation code I would use:

from pylab import *
from numpy import ma
import time


X,Y = meshgrid( arange(0,2*pi,.04),arange(0,2*pi,.04) )
U = cos(X)
V = sin(Y)

fig = figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
for i in range(90):
    Q = ax.quiver( U, V)
    time.sleep(0.2)

I know this simple snippet isnt drawing to screen (leak becomes worse then).

Q has a sys.getrefcount of 4 so nothing I am able to do seems to get rid of it. Calls to fig and ax clear only reduce the refcount to 2. Telling Q to remove() itself doesnt help.

My code is much more complex than this. I have tried completely replacing the axes objects but that doesnt help. I really am not free to replace the Figure instance.

@efiring
Copy link
Member

efiring commented Oct 28, 2013

Confirmed.
It happens even if one merely creates the Quiver object directly.
I think the problem is that each time a Quiver object is created, it registers another instance function in the list of "dpi_changed" callbacks for the figure object.
Git blame shows the callback registration as dating from 2008, commit 9b4ffcc. It looks like the use of a proxy in CallbackRegistry is supposed to prevent this problem; I don't understand it well enough to see what is going wrong here. @pelson? @mdboom?

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Oct 29, 2013
Fixes it in two ways:

1) changes the closure of `on_dpi` to be over a weakref, not `self`
2) cleans up the call back when the quiver is removed
@tacaswell
Copy link
Member

I think the problem really goes back to b66aa38 , the registration in 9b4ffcc is is quiver_key not quiver.

I suspect is what is going on is that the function has a weakref to it from the callback, but the function contains a reference to the Quiver object (and I suspect this is made worse because it was bound by closing over self, not as an honest instance method.

If you search the repo on on_dpi_change you find a whole bunch of places which probably have the same problem.

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Jan 14, 2014
tests memory leaks reported in issue matplotlib#2556
mdboom added a commit that referenced this issue Jan 27, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants