Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e11f0f9

Browse files
committed
fixed mem leaks in transforms and agg
svn path=/trunk/matplotlib/; revision=422
1 parent 059d7d6 commit e11f0f9

10 files changed

Lines changed: 67 additions & 24 deletions

CHANGELOG

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
New entries should be added at the top
22

3+
2004-07-21 Applied backend_agg memory leak patch from hayden
4+
- [email protected]. Found and fixed a leak in binary
5+
operations on transforms. Moral of the story: never incref
6+
where you meant to decref!- JDH
7+
8+
2004-07-21 Fixed a to string memory allocation bug in agg and image
9+
modules - JDH
10+
311
2004-07-21 Added mpl_connect and mpl_disconnect to matlab interface -
412
JDH
513

TODO

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,10 +469,16 @@
469469

470470
-- font dict in wx is broken w/ respect to new font names
471471

472-
-- update nav section of tutorial
472+
-- DONE update nav section of tutorial
473473

474474
-- track down transforms memleak
475475

476476
-- DONE make sure you handle cacheing of rotated mathtext properly
477477

478-
- handle deprecated connect across backends graciously
478+
-- handle deprecated connect across backends graciously
479+
480+
-- embedding_in_wx3 seems broken with numeric
481+
482+
-- add new connect to API_CHANGES
483+
484+
--port new toolbar to embedding examples

examples/embedding_in_gtk.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from matplotlib.numerix import arange, sin, pi
33

44
import matplotlib
5-
matplotlib.use('GTK')
5+
matplotlib.use('GTKAgg') # or 'GTK'
66

77
from matplotlib.axes import Subplot
8-
from matplotlib.backends.backend_gtk import FigureCanvasGTK
8+
9+
# swith comments for gtk over gtkagg
10+
#from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
11+
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
912
from matplotlib.figure import Figure
1013

1114
import gtk
@@ -26,7 +29,7 @@
2629
a.plot(t,s)
2730

2831

29-
canvas = FigureCanvasGTK(f) # a gtk.DrawingArea
32+
canvas = FigureCanvas(f) # a gtk.DrawingArea
3033
vbox.pack_start(canvas)
3134

3235
#button = gtk.Button('Quit')

examples/embedding_in_gtk2.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
from matplotlib.numerix import arange, sin, pi
33

44
import matplotlib
5-
matplotlib.use('GTK')
6-
from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
5+
matplotlib.use('GTKAgg') # or 'GTK'
6+
7+
# swith comments for gtk over gtkagg
8+
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
9+
#from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
10+
11+
# or NavigationToolbar for classic
12+
from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar
713

814
from matplotlib.axes import Subplot
915
from matplotlib.figure import Figure
@@ -26,11 +32,11 @@
2632
ax.plot(t,s)
2733

2834

29-
canvas = FigureCanvasGTK(fig) # a gtk.DrawingArea
35+
canvas = FigureCanvas(fig) # a gtk.DrawingArea
3036
canvas.show()
3137
vbox.pack_start(canvas)
3238

33-
toolbar = NavigationToolbar(canvas, win)
39+
toolbar = NavigationToolbar(canvas)
3440
toolbar.show()
3541
vbox.pack_start(toolbar, gtk.FALSE, gtk.FALSE)
3642

examples/embedding_in_wx2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22
"""
3-
An example of how to use wx or wxagg in an application w. or w/o the toolbar
3+
An example of how to use wx or wxagg in an application with the new
4+
toolbar - comment out the setA_toolbar line for no toolbar
45
"""
56

67
from matplotlib.numerix import arange, sin, pi
@@ -14,7 +15,7 @@
1415
# comment out the following to use wx rather than wxagg
1516
matplotlib.use('WXAgg')
1617
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
17-
from matplotlib.backends.backend_wx import NavigationToolbarWx as NavigationToolbar
18+
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
1819

1920
from matplotlib.figure import Figure
2021

@@ -34,7 +35,6 @@ def __init__(self):
3435
s = sin(2*pi*t)
3536

3637
self.axes.plot(t,s)
37-
3838
self.canvas = FigureCanvas(self, -1, self.figure)
3939

4040
self.sizer = wxBoxSizer(wxVERTICAL)
@@ -46,7 +46,7 @@ def __init__(self):
4646

4747

4848
def add_toolbar(self):
49-
self.toolbar = NavigationToolbar(self.canvas, True)
49+
self.toolbar = NavigationToolbar2Wx(self.canvas)
5050
self.toolbar.Realize()
5151
if wxPlatform == '__WXMAC__':
5252
# Mac platform (OSX 10.3, MacPython) does not seem to cope with

examples/embedding_in_wx4.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,21 @@
1515
# comment out the following to use wx rather than wxagg
1616
matplotlib.use('WXAgg')
1717
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
18-
from matplotlib.backends.backend_wx import NavigationToolbarWx as NavigationToolbar
18+
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
1919

2020
from matplotlib.backends.backend_wx import _load_bitmap
2121
from matplotlib.figure import Figure
2222
from matplotlib.numerix import rand
2323

2424
from wxPython.wx import *
2525

26-
class MyNavigationToolbar(NavigationToolbar):
26+
class MyNavigationToolbar(NavigationToolbar2Wx):
2727
"""
2828
Extend the default wx toolbar with your own event handlers
2929
"""
3030
ON_CUSTOM = wxNewId()
3131
def __init__(self, canvas, cankill):
32-
NavigationToolbar.__init__(self, canvas, cankill)
32+
NavigationToolbar2Wx.__init__(self, canvas)
3333

3434
# for simplicity I'm going to reuse a bitmap from wx, you'll
3535
# probably want to add your own.

src/_backend_agg.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,13 @@ RendererAgg::write_png(const Py::Tuple& args)
969969
info_ptr = png_create_info_struct(png_ptr);
970970
if (info_ptr == NULL) {
971971
fclose(fp);
972-
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
972+
png_destroy_write_struct(&png_ptr, &info_ptr);
973973
throw Py::RuntimeError("could not create info struct");
974974
}
975975

976976
if (setjmp(png_ptr->jmpbuf)) {
977977
fclose(fp);
978-
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
978+
png_destroy_write_struct(&png_ptr, &info_ptr);
979979
throw Py::RuntimeError("error building image");
980980
}
981981

@@ -997,7 +997,15 @@ RendererAgg::write_png(const Py::Tuple& args)
997997
png_write_info(png_ptr, info_ptr);
998998
png_write_image(png_ptr, row_pointers);
999999
png_write_end(png_ptr, info_ptr);
1000-
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
1000+
1001+
/* Changed calls to png_destroy_write_struct to follow
1002+
http://www.libpng.org/pub/png/libpng-manual.txt.
1003+
This ensures the info_ptr memory is released.
1004+
*/
1005+
1006+
png_destroy_write_struct(&png_ptr, &info_ptr);
1007+
1008+
10011009
fclose(fp);
10021010

10031011
return Py::Object();
@@ -1176,6 +1184,7 @@ RendererAgg::~RendererAgg() {
11761184
delete slineP8;
11771185
delete slineBin;
11781186
delete theRasterizer;
1187+
delete theRenderer;
11791188
delete rendererBin;
11801189
delete rendererBase;
11811190
delete pixFmt;

src/_transforms.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ BinOp::BinOp(LazyValue* lhs, LazyValue* rhs, int opcode) :
105105

106106
BinOp::~BinOp() {
107107
_VERBOSE("BinOp::~BinOp");
108-
Py_INCREF(_lhs);
109-
Py_INCREF(_rhs);
108+
Py_DECREF(_lhs);
109+
Py_DECREF(_rhs);
110110
}
111111

112112
Py::Object

unit/helpers.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
from matplotlib.transforms import one, Point, Value, Bbox, get_bbox_transform
55

66

7+
def rand_val(N = 1):
8+
if N==1: return Value(rand())
9+
else: return [Value(val) for val in rand(N)]
10+
711
def rand_point():
8-
xy = rand(2)
9-
return Point( Value(xy[0]), Value(xy[1]) )
12+
return Point( rand_val(), rand_val() )
1013

1114
def rand_bbox():
1215
ll = rand_point()

unit/transform_memleak.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys, time, os
2-
from helpers import rand_transform
2+
from helpers import rand_val, rand_point, rand_bbox, rand_transform
33

44
def report_memory(i):
55
pid = os.getpid()
@@ -9,6 +9,14 @@ def report_memory(i):
99

1010
N = 200
1111
for i in range(N):
12+
v1, v2, v3, v4, v5 = rand_val(5)
13+
b1 = v1 + v2
14+
b2 = v3 -v4
15+
b3 = v1*v2*b2 - b1
16+
17+
18+
p1 = rand_point()
19+
box1 = rand_bbox()
1220
t = rand_transform()
1321
val = report_memory(i)
1422
if i==1: start = val

0 commit comments

Comments
 (0)