User:Bettercom/code/leaktest

From OpenStreetMap Wiki
Jump to: navigation, search

The problem

Working with the py-API of mapnik I ran into a serious problem: my app leaked memory. Here's the code to reproduce this problem. When

  • m = Map(2 * 256, 2 * 256) and
  • load_map(m, MAPFILE)

are part of a function (and not only once instantiated global) not only the app becomes much more slower (because it takes time to instantiate m and calling load_map) but also the Map does not get destroyed when the function finishes. Unfortunately the garbage-collector of python does not report any problems. For me it's unclear whether this is a mapnik-issue or is similar to a (former?) issue with python-boost.

Environment

[ml@h1 /mnt/mapnik/leaktest]$ uname -a
FreeBSD h1.bettercom.de 7.2-RELEASE FreeBSD 7.2-RELEASE #2: Mon Jun 29 20:33:00 CEST 2009     root@h1.bettercom.de:/usr/obj/usr/src/sys/H1KERNEL  i386
[ml@h1 /mnt/mapnik/leaktest]$ pkg_info -xI boost python mapnik
boost-python-1.37.0_1 Free peer-reviewed portable C++ source libraries
mapnik-0.6.0_1        A Free Toolkit For Developing Mapping Applications
python26-2.6.2        An interpreted object-oriented programming language

The code

#!/usr/bin/env python
import resource
from mapnik import *
mfile = '/mnt/mapnik/osm.xml'
for i in range(10):
    m=Map(512,512)
    load_map(m, mfile)
    print 'ru_maxrss: %s kB, ru_ixrss: %s' % (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss, resource.getrusage(resource.RUSAGE_SELF).ru_ixrss)
    del m

Results

ru_maxrss: 18108 kB, ru_ixrss: 73568
ru_maxrss: 19284 kB, ru_ixrss: 115192
ru_maxrss: 20444 kB, ru_ixrss: 156816
ru_maxrss: 21568 kB, ru_ixrss: 196504
ru_maxrss: 22752 kB, ru_ixrss: 238128
ru_maxrss: 23968 kB, ru_ixrss: 279752
ru_maxrss: 25156 kB, ru_ixrss: 321376
ru_maxrss: 26332 kB, ru_ixrss: 363000
ru_maxrss: 27440 kB, ru_ixrss: 404624
ru_maxrss: 28676 kB, ru_ixrss: 449152

As you can see each loop eats up more than 1M memory - the del statement does nothing.

Conclusion

Any instance of Map should be instantiated only once globally or in the module - and not in a function. At least not if this function gets called more than one time in an application.

--Bettercom 17:06, 4 July 2009 (UTC)