User Tools

Site Tools


ardour:memoryleak

This is an old revision of the document!


The Ardour memory leak

Ardour has for a very long time been having a pretty nasty memory leak, somehow connected to its undo history list.
The author implemented a way to no store more than a given number of elements in the list, but this did not seem to fix the issue.
The problem manifests itself whenever an action is performed, by allocating an amount of memory, growing with number of actions taken to reach the current point in the project. In other words, the longer you work, the more memory one action will take up.
The leak is particularly nasty when working on big projects with 16 or more tracks, in which high end computers with as much as 4GB of memory will quickly be sent to its knees.

I have set out to hunt down this malicious bug.

Analysis

I started by editing the Command class in the embedded pbd library, located in the libs/pbd/pbd/command.h file:

class Command : public PBD::StatefulDestructible
{
public:
  Command() { printf("Command: %p\n", this); }
  virtual ~Command() { printf("Command: %p (delete)\n", this); }
  virtual void operator() () = 0;
  virtual void undo() = 0;
  virtual void redo() { (*this)(); }
  virtual XMLNode &get_state();
  virtual int set_state(const XMLNode&) { /* noop */ return 0; }
};

This prints out the pointer to a newly created Command object (and all classes inheriting it), and also prints out its pointer, when it is about to be deleted.
This quickly showed me that a lot of these objects are created, but none of the ever deleted again (not even when closing the project).

Test

My idea was then to try and delete all the objects when they were inserted into the undo list.
This was done by editing the Undo class, also vacated in the pbd library (libs/pbd/undo.cc)

void
UndoTransaction::add_command (Command *const action)
{
  delete action;
 
  /* catch death */
  // new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death);
  // actions.push_back (action);
}

This now deletes all Command objects at the time of insertion into the undo history list, thus totally disabling all undo functionality.
I then tested some of my larger projects, and could conclude that my changes indeed did lower the memory allocation problem.
I guess the idea of the ProxyShiva is somehow to delete the 'Command object automatically when it is no longer needed, but this is obviously not working as intended.
Furthermore I want to point out that there are still
Command'' objects that are not being deleted (selections for example), and my guess is that these command are not meant to be undoable, but they should definitely still be deleted somewhere.

I hope this page might be of some use for the Ardour developers in the continuous work to improve Ardour to become one of the worlds leading DAWs!

Written by Bent Bisballe Nyeng (deva@aasimon.org)

ardour/memoryleak.1226160065.txt.gz · Last modified: 2008/11/08 17:01 by deva