how to find a memory leak

Hello,

I am interested to find out if there is any software that I can use to find any memory leaks in my xojo application.

Thanks

Instruments from Apple comes included with Xcode.

or submerge it in a tank of water and look for bubbles

1 Like

If it’s an object leak due to a reference not getting cleared or a circular reference not getting broken then you can use this little snippet to walk all the objects that the framework knows about and see if the counts are going up. If it’s something else that you’re allocating and not disposing of then this wont help. I use this in a temporary window with nothing but a button to run it and a text area to place the output in. Run it periodically and see if you have more of any kind of object than you expect to.

This code predates the array.sortwith() functionality so I sort the 2 arrays together by concatenating them into a string in a string sortable format :wink: Were I to do that today it wouldn’t be necessary. It also predates the ENDOFLINE functionality :wink: Boy… this is old :wink: I did just use it the other day to find a problem though, so it still works!

Last line puts the output into textArea1 which obviously will error unless you have someplace to put it.

dim d as Dictionary
dim i, count as Integer
dim s, out as string
dim SortArray(0) as string
dim cr as string = chr(13) + chr(10)

count = Runtime.ObjectCount - 1
out = "Object Count: " + str( count+1) + cr
out=out+ "Memory Used: " + format( Runtime.MemoryUsed, “#,”) + cr + cr

d = new Dictionary

for i = 0 to count

s = Runtime.ObjectClass( i)

if d.HasKey( s) then
  d.value( s) =  d.Value( s) + 1
else
  d.Value( s) = 1
end if

next

count = d.Count - 1
Redim SortArray( count)

for i = 0 to count
SortArray( i) = Format( d.Value( d.Key( i)), “000000”) + “:” + d.Key( i)
next

SortArray.Sort

for i = 0 to count
out = out + NthField( SortArray( i), “:”, 1) + " " + NthField( SortArray( i), “:”, 2) + cr
next

TextArea1.AppendText( out)

if you have object with parent -> child relation ship, you may want to make sure that any child holding a reference to a parent uses a weak reference for that.

or that you specifically break the parent child relationship when you’re cleaning up the objects. The trap is doing it in the destructor. The destructor wont get called until all the references are gone, which they wont ever be if you’re using the destructor to break them.

back before weak references we just created a close or cleanup method that broke any such things :wink:

But just cleaning up you own code does not mean that there will be no leaks. The Xojo framework itself has leaks… finding them is difficult and fixing them might be impossible…

If on Windows, you can try this quick & dirty method:
Open Task Manager
Switch to Details tab (on Windows 10 - it may be called something different on older versions)
Right-click the column headings and turn on

  Handles
  Threads
  User Objects
  GDI Objects

Run your app and watch the #s.

In the case when your Xojo objects are not leaking, but the framework (or a third party plugin) is leaking Windows OS objects, you may catch it.

The last time I used that method to search for a memory leak, I almost drowned.

For a rough test: When I finished a class and have tested it enough to believe it could be fairly ok, I usually create a simple test window with a button that creates instances of this class in a loop, modify these instances’ properties that deliver classes themselves and watch Activity Monitor for the RAM consumption of the app while I click the button repeatedly and then pause to see if memory is released.
For testdriving declared classes, I have a debug boolean that when enabled spills out debug information in the classes’ destructor including the ARC count.

Instruments has come a long way, it’s much easier to figure out what you’re leaking and also the stack of the leaking object.

I’m using it at the moment to resolve some CoreGraphics & CoreImage issues.

Instruments rocks - in fact I’ll plug my own feedback report to show how it can not only tell you what was leaked, but (da dum!) who leaked it: feedback://showreport?report_id=34107 See the screenshots especially the “Feedback-000001.png” one which shows how Instruments shows you the Library and Method name that leaked the object. Smoking gun :slight_smile:

resurrecting an old thread sorry. But instruments doesn’t always show you anything useful at all. Right now I’m looking at an app that instruments says leaks something different every time and sometimes not leaking even though memory usage is constantly increasing. Right now I’m looking at hundreds of 96 byte “__NSCFString” being leaked each 10 second testing interval. This morning it was core image structures being leaked, but no more. Just a recompile and it’s something different now. Yet the app is definitely leaking. For my current NSCFStrings leaking the responsible library and Frame are completely blank. Though it has gathered the data that was leaked but no stack trace. The data however is in hex in a window where I can’t highlight and copy it to try to see if it has anything recognizable in it.

I am so sick of memory leaks in code I didn’t write right now. whats a few hundred meg lost? Just make sure you’re compiled to 64 bit so you can keep leaking memory for months and it will happily swap it out.

I think I’m taking the weekend off and not going to look at a single line of code, thats how pissed off I am at leaking a hundred meg in an afternoon with absolutely no information form instruments that I can use and no increase in my own object counts so it’s not my fault.

From what I can gather Xcode has some new shiny tools built-in, so it could be that they’re letting Instruments fall to the way side; just like Quartz Composer :frowning:

Well, I can normally only track leaks which create thousands of objects and leak a couple of megabytes.
All those small leaks of a few bytes are nearly impossible to locate.

BTW, I found the Runtime object iterator utterly useless because it includes its own objects it creates. I had also tried to write smart code that would use introspection to check an object and all its dependencies for a circular reference, but that also fails once you run into items with arrays, because Introspection, or rather the Variant type, doesn’t let you access the elements if you don’t hard-code the correct array element type for them. There used to be an actually useful function in the early days called DebugDumpObjects, but that got removed in the wrong belief that the new Runtime module could replace it and be better at it, when in fact it got worse. Sad story that never seemed to interest anyone at Real after breaking it (in fact, at that time I worked for them and tried to get it working again but was kicked out before I could finish it).

James, is your app using HTMLViewers or any other plug-ins? Javascript and other Cocoa code may be garbage-collected rather than reference-counted, in which case you will see what appears to be “leaks” but which are actually just garbage building up, which will be eventually collected. I spent a number of hours tracking “leaks” in HTMLViewer/JavaScript code which turned out to be not a leak.

I don’t think modern Cocoa does Garbage collection anymore, something to do with cuts to local governments… Although don’t hold me to it as some API uses ‘lazy’ reference counting. Which means that the memory gets released whenever the OS deems necessary, sounds a lot like Garbage Collection to me!

Lazy APIs are a PITA, not just for leak checking, but also when working with the App Sandbox, as it may not load the file contents when your application has access to the file.