Hi Y'all,

I have a long running text mode application (an Asterisk interface) which
uses Urwid and Twisted. The library itself performs the functions I require,
but I notice over time my little application consumes more and more memory.

For my main call list window, I started out using a SimpleListWalker and
switched to the default of the ListBox - the PollingListWalker which solved
one leak, but then I observed that whenever I opened an additional window,
objects accumulated which were not released. The Python version I have tried
this on is 2.5.2 and the 2.5 generation from Debian Etch.

I attach a sample which demonstrates the problem. Iterating using Test()
produces the memory leak as more and more objects are tracked by the garbage
collector but don't seem to be returned or collected and are yet not
uncollectable. I created an alternative (Test2()) which simply allocates and
then pops from a list. At the end of each procedure, the procedure's non
externally referenced variables should be disposed, but the objects from
Test() persist and grow.

I am sure there must be a very simple explanation why this happens. Perhaps
someone could explain it.

Many thanks.
#!/usr/bin/python

import logging, gc
import urwid.curses_display
from sys import stdin
from urwid import *
from time import sleep

ITER = 1000000
LOG_FILE="memory.log"

gc.set_threshold(1, 1, 1)

ui = None

logging.basicConfig(
  level=logging.DEBUG, filename=LOG_FILE,
  format="%(asctime)s %(levelname)s %(message)s"
)
    
Palette = [
  ("body", "light gray", "dark blue"),
  ("header", "dark blue", "light gray"),
  ("footer", "yellow", "dark blue")
]

def Test(idx):
  logging.debug("GC TRACKING %d OBJECTS" % len(gc.get_objects()))
  caption = AttrWrap(Text(("header", "Test Window %d" % idx), align="center"), "header")
  hint = AttrWrap(Text(("footer", "Test Window Footer"), align="center"), "footer")
  content = AttrWrap(Filler(Text("This is a test", align="center")), "body")
  content = Frame(content, header=caption, footer=hint)
  content = Padding(content, "center", 60)
  content = Filler(content, "middle", 25)
  area = ui.get_cols_rows()
  ui.draw_screen(area, content.render(area, True))
  sleep(0.25)

def Test2():
  logging.debug("GC TRACKING %d OBJECTS" % len(gc.get_objects()))
  l = ["THIS IS A TEST STRING %10d" % c for c in range(1, ITER)]
  for c in range(1, ITER): l.pop()

def Runner():
  for c in range(1, ITER): Test(c)

ui = urwid.curses_display.Screen()
ui.register_palette(Palette)
ui.run_wrapper(Runner)
_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid

Reply via email to