Memory leaks on OS X

Assuming you have Xcode installed, OS X comes with a handy set of developer diagnostic tools called ‘Instruments’ – find the main program under /Developer/Applications/. To use them with a Delphi application, do this:

  • Run the application first. Don’t run it through the Delphi debugger, but via PAServer is still OK (meaning, choosing Run without Debugging in the IDE). Running via PAServer is useful because it provides a ready output for WriteLn calls (unlike on Windows, these will always work on a Mac, regardless of whether {$APPTYPE CONSOLE} is set).
  • Open Instruments and select your Instrument.
  • Click the Choose Target combo box at the top of the Instruments window, and select Attact to Process followed by the name of your application.
  • Click on the red Record button to the left of the combo box.
  • Go back to your application and do some stuff. Instruments will periodically update with info.
  • To stop recording, press the Record button (now labelled Stop) again.

Unfortunately, using the memory leaks ‘instrument’, I’ve discovered Delphi applications leak like the proverbial sieve. Try this: create a new FireMonkey HD application, add a button to the form, and handle the button’s OnClick event by calling ShowMessage. Add OS X as a target, run the application, then open Instruments, select Leaks, and do the steps just listed. Click the button a few times, and the leak list gets enormous:

Checking the source, some obvious bloopers causing this are in Macapi.ObjectiveC.pas: several times a local TList is created in order to construct a dynamic array, but then never freed. So, copy Macapi.ObjectiveC.pas into your project’s source directory, add it to the project, then look for any .ToArray calls: in all, I’ve counted 5 that should be followed by freeing the source object (4 TLists and 1 TDictionary).

Run the revised application under Instruments again, and a good wad of leaks should have gone (in the screenshots, compare the respective vertical scroll bars):

Of the leaks remaining, those with ‘TFMXWindowDelegate’ in their description caught my eye: from experimenting with writing a delegate object for NSAlert, I’ve learnt a delegate implementation should explicitly release the Objective-C part of itself (the NSObject part I guess) in Destroy, since no one else will do so. So, now copy FMX.Platform.Mac.pas into your project’s source directory, add it to the project, then add the following line at the end of TFMXWindowDelegate.Destroy:

  CFRelease(GetObjectID);

Run the application again through Instruments, and a few more leaks will have disappeared compared to before. However, there’s still quite a few remaining:

A tried a few more things, but nothing was successful. To be honest, the most disappointing thing in all this is the fact it appears not just the FireMonkey layer is leaking – before looking into this, I had been finding the compiler and RTL to have been given a level of care and attention on the Mac that FMX could only dream of.

Anyhow, I’ve reported the two partial fixes I did come up with to QC (see report nos. 100788 and 100789).

Advertisements

3 thoughts on “Memory leaks on OS X

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s