Adventures in tracking down a memory leak in Gliffy

Gliffy was noticeably slowing down when used for an extended period of time, and we suspected a memory leak was the cause. Fortunately, the fine folks at Laszlo have built some excellent tools into the debugger which make tracking down such issues a heck of a lot easier.

Our adventure begins with a look at the docs which discuss hunting down memory leaks. Using the procedure described in the docs, I discovered that the objects which represent undo were not being picked up by the garbage collector. Objects will not be picked up by the garbage collector if any references to those objects exist.

Laszlo Debugger

Another interesting thing I noticed was that the class definition of undo did not explicitly extend another class. When a class definition does not extend another class, it is implied that the class extends <view>, NOT <node> as you might expect. In this case, our undo object does not have a visual component to it, and as such what we really want is to extend <node>.

If you’ve instantiated Laszlo objects at run time before, you know that the first argument of the constructor is the parent node of the constructed object. In our case, it didn’t really make sense for the undo object to have a parent, and thusly none was defined. If you take a look at the source code for LaszloView.as (in the source distribution) you’ll see that when a parent is not defined in the constructor, the canvas is assumed to be the parent.

Ah-hah! We’ve found where the reference to our undo objects were coming from. Simply checking the contents of canvas.subviews in the debugger offered verification. Further investigation revealed that constructing a <node> without an explicit parent does not cause the canvas to be defined as the parent. Thusly, by simply having our undo class extend <node>, I was able to fix the memory leak. Yay!

Lessons learned:

  • Always extend <node> if there is no visual component to the class you are defining.
  • When instantiating subclasses of LzView at run-time, be aware of the implied parent if you don’t supply your own.
  • PairProgramming or code reviews probably would have caught this issue in advance. Even busy little start-ups should be taking the time to implement good code review practices.