Search code examples
iosswiftinstruments

Allocations instrument tool in Swift not providing detailed enough information


I am attempting to use the allocations tool to profile a Swift 2 iOS app. I am doing this like so:

  1. Run the app using the Allocations tool.
  2. Once the app is booted, I wait 10 seconds and hit "Mark generations"
  3. I open the screen I suspect has a memory leak, wait 10 seconds, close it, wait some more, and then hit "Mark generations"

At this point, I look at the second generation to see objects that were never released. My trouble is that the biggest offender is always just "main", which does not point to any specific classes or methods enter image description here

As demonstrated above, "main" is responsible for almost 80% of the memory leaks, but the stacktrace does not point anywhere specific, unlike the leaks below it which point to specific methods.

I am not sure if this is related, but when I go to File -> Symbols, I am showing one missing symbol, like this. However, I cannot find this symbol on anywhere on my machine: enter image description here

My questions is: Is it normal for this "main" to be holding on to this much memory, or is something misconfigured on my end to where I am not able to see the real stacktrace?


Solution

  • So a couple things to consider.

    1: To get a sense of what objects are allocated and then never released you should consider using the allocation summary instead of generations. To find the Allocation Summary look next to the Details button where it says Generations. Click Generations and then switch to Statistics. Then in the search bar type in the name of your app (In my case Fleet.) and Instruments will filter the allocations to only objects you have created. See below for an example of what the screen should look like.

    example

    Now, to find out if an object hasn't been deallocated you want to look at the Persistent and the Transient columns. The Persistent column shows the number of objects that currently exist while the Transient column shows the number of objects that have existed but have been deallocated. So if you expect an object to be deallocated but the number in the Transient column doesn't change then you know the object hasn't been deallocated and you have a problem!

    2: If you still want to use Generations to figure out what is taking up all that memory you can uncheck the Invert Call Tree & Hide System Libraries options. For example, on my screen (shown below) you'll see that main take up 76.5% of the allocated memory in Generation A. Drilling down I'm able to discover that the majority of that allocation, 45.2%, goes to UIImages.

    example

    For more details and an amazing tutorial on Instruments see: https://www.raywenderlich.com/97886/instruments-tutorial-with-swift-getting-started

    Hope this helps! 😄