Re: [Matplotlib-users] savefig Memory Leak
On 2010-04-16 19:18:56 +0200, Keegan Callin said: Hello, I have written a small script that, I think, demonstrates a memory leak in savefig. A search of the mailing list shows a thread started by Ralf Gommers ralf.gomm...@googlemail.com about 2009-07-01 that seems to cover a very similar issue. I have appended the demonstration script at the end of this e-mail text. [kee...@grizzly ~]$ python2.6 Python 2.6.4 (r264:75706, Jan 20 2010, 12:34:05) [GCC 4.4.2 20091222 (Red Hat 4.4.2-20)] on linux2 Type help, copyright, credits or license for more information. import matplotlib matplotlib.__version__ '0.99.1.1' ''' # Import standard python modules import sys import os from ConfigParser import SafeConfigParser as ConfigParser from cStringIO import StringIO # import numpy import numpy from numpy import zeros # Import matplotlib from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas def build_figure(a): '''Returns a new figure containing array a.''' # Create figure and setup graph fig = Figure() Could you try to use figure() instead of Figure()? That often creates a mess on my side. Or should one use Figure() in the 'Artist's style? I am still importing pyplot as plt, and in that case, I have to use figure(), otherwise things don't work. I also had the feeling of a leak and am currently doing this without much 'leaking': :) fig = plt.figure() ax = fig.add_subplot(111) im = ax.imshow(nData) cb = plt.colorbar(im) ax.set_title(bname + ', ' + mode) fig.savefig(filename + '.equal.png') plt.close(fig) I think, the plt.close(fig) was quite important in my case. Give it a try! Best regards, Michael -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Re: [Matplotlib-users] savefig Memory Leak
Hello Michael, I have not tried using plt.figure() and plt.close(fig) but you are right; I should investigate it as well for completeness. I had, actually, purposefully avoided doing this because I read that the pyplot API is stateful. It keeps references to figures in the same way that MatLab does and these figures need to be explicitly closed (via plt.close). By calling Figure(...) directly I am trying to use matplotlib's object-oriented API and avoid pyplot's statefullness. Something interesting and perhaps enlightening is to switch backends from Agg to something else (say Cairo). In the demonstration script that I posted you would do so like this: #from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas When using the Cairo backend the memory leak disappears. In my mind, this indicates a memory leak when using the Agg backend that DOES NOT appear when using the Cairo backend. Thanks for the advice; I will give pyplot a try and see if I get different behaviour. Sincerely, Keegan Callin On 04/19/2010 11:28 AM, K.-Michael Aye wrote: Could you try to use figure() instead of Figure()? That often creates a mess on my side. Or should one use Figure() in the 'Artist's style? I am still importing pyplot as plt, and in that case, I have to use figure(), otherwise things don't work. I also had the feeling of a leak and am currently doing this without much 'leaking': :) fig = plt.figure() ax = fig.add_subplot(111) im = ax.imshow(nData) cb = plt.colorbar(im) ax.set_title(bname + ', ' + mode) fig.savefig(filename + '.equal.png') plt.close(fig) I think, the plt.close(fig) was quite important in my case. Give it a try! -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
[Matplotlib-users] savefig Memory Leak
Hello, I have written a small script that, I think, demonstrates a memory leak in savefig. A search of the mailing list shows a thread started by Ralf Gommers ralf.gomm...@googlemail.com about 2009-07-01 that seems to cover a very similar issue. I have appended the demonstration script at the end of this e-mail text. The demonstration script script sits in a relatively tight loop creating figures then saving them while monitoring memory usage. A plot of VmRSS vs. number of loop iterations as generated on my system is attached as data.png (you can create your own plots with the sample script). Although I have only tested this on Fedora 12, I expect that most Linux users should be able to run the script for themselves. Users should be able to comment out the savefig line and watch memory usage go from unbounded to (relatively) bounded. Can anybody see a cause for this leak hidden in my code? Has anybody seen this issue and solved it? I would also appreciate it if other people would run this script and report their findings so that there will be some indication of the problem's manifestation frequency. Sincerely, Keegan Callin '''Script to demonstrate memory leakage in savefig call. Requirements: Tested in Fedora 12. It should work on other systems where /proc/{PID}/status files exist and those files contain a 'VmRSS' entry (this is how the script monitors its memory usage). System Details on Original Test System: [kee...@grizzly test]$ uname -a Linux grizzly 2.6.32.9-70.fc12.x86_64 #1 SMP Wed Mar 3 04:40:41 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux [kee...@grizzly ~]$ gcc --version gcc (GCC) 4.4.3 20100127 (Red Hat 4.4.3-4) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [kee...@grizzly ~]$ cd ~/src/matplotlib-0.99.1.1 [kee...@grizzly matplotlib-0.99.1.1]$ rm -rf build [kee...@grizzly matplotlib-0.99.1.1]$ python setup.py build out.log [kee...@grizzly matplotlib-0.99.1.1]$ head -38 out.log BUILDING MATPLOTLIB matplotlib: 0.99.1.1 python: 2.6.4 (r264:75706, Jan 20 2010, 12:34:05) [GCC 4.4.2 20091222 (Red Hat 4.4.2-20)] platform: linux2 REQUIRED DEPENDENCIES numpy: 1.4.0 freetype2: 9.22.3 OPTIONAL BACKEND DEPENDENCIES libpng: 1.2.43 Tkinter: no * TKAgg requires Tkinter wxPython: no * wxPython not found Gtk+: no * Building for Gtk+ requires pygtk; you must be able * to import gtk in your build/install environment Mac OS X native: no Qt: no Qt4: no Cairo: no OPTIONAL DATE/TIMEZONE DEPENDENCIES datetime: present, version unknown dateutil: matplotlib will provide pytz: 2010b OPTIONAL USETEX DEPENDENCIES dvipng: no ghostscript: 8.71 latex: no pdftops: 0.12.4 [Edit setup.cfg to suppress the above messages] [kee...@grizzly matplotlib-0.99.1.1]$ bzip2 out.log # out.log.bz2 is attached to the message containing this program. [kee...@grizzly ~]$ python2.6 Python 2.6.4 (r264:75706, Jan 20 2010, 12:34:05) [GCC 4.4.2 20091222 (Red Hat 4.4.2-20)] on linux2 Type help, copyright, credits or license for more information. import matplotlib matplotlib.__version__ '0.99.1.1' ''' # Import standard python modules import sys import os from ConfigParser import SafeConfigParser as ConfigParser from cStringIO import StringIO # import numpy import numpy from numpy import zeros # Import matplotlib from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas def build_figure(a): '''Returns a new figure containing array a.''' # Create figure and setup graph fig = Figure() FigureCanvas(fig) ax = fig.add_subplot(1, 1, 1) ax.plot(a) return fig _proc_status = '/proc/%d/status' % os.getpid() def load_status(): '''Returns a dict of process statistics from from /proc/{PID}/status.''' status = {} with open(_proc_status) as f: for line in f: key, value = line.split(':', 1) key = key.strip() value = value.strip() status[key] = value return status def main(): data_file = 'data.txt' image_file = 'data.png' num_iterations = 1000 with open(data_file, 'w') as f: # Tried running without matplotlib or numpy such that the #