As a follow up to my previous How can I create a reference cycle using dispatchQueues?:
For the strong references (that create leaks, but aren't reference cycles) e.g. Timer
, DispatchSourceTimer
, DispatchWorkItem
, the memory graph doesn't create a purple icon, I suspect it's simply because it doesn't find two objects pointing back to each other strongly.
I know I can go back and forth and observe that a specific class is just not leaving the memory, but wondering if Xcode is providing anything more.
You ask:
For the strong references (that create leaks, but aren't reference cycles) e.g.
Timer
,DispatchSourceTimer
,DispatchWorkItem
, the memory graph doesn't create a purple icon, I suspect it's simply because it doesn't find two objects pointing back to each other strongly.
Yes. Or more accurately, the strong reference cycle warning is produced when there are two (or more objects) whose only strong references are between each other.
But in the case of repeating timers, notification center observers, GCD sources, etc., these are not, strictly speaking, strong reference cycles. The issue is that the owner (the object that is keeping a strong reference to our app’s object) is just some persistent object that won’t get released while our app is running. Sure, our object might still be “abandoned memory” from our perspective, but it’s not a cycle.
By way of example, consider repeating timer that is keeping strong reference to our object. The main runloop is keeping strong reference to that timer and won’t release it until the timer is invalidated. There’s no strong reference cycle, in the narrow sense of the term, as our app doesn’t have strong reference back to the runloop or the timer. But nonetheless, the repeating timer will keep a strong reference to our object (unless we used [weak self]
pattern or what have you).
It would be lovely if the “Debug Memory Graph” knew about these well-known persistent objects (like main runloop, default notification center, libDispatch, etc.), and perhaps drew our attention to those cases where one of these persistent objects were the last remaining strong reference to one of our objects. But it doesn’t, at least at this point.
This is why we employ the technique of “return to point that most of my custom objects should be have been deallocated” and then “use ‘debug memory graph’ to identify what wasn’t released and see what strong references are persisting”. Sure, it would be nice if Xcode could draw our attention to these automatically, but it doesn’t.
But if our app has some quiescent state, where we know the limited types of objects that should still be around, this “debug memory graph” feature is still extremely useful, even in the absence of some indicator like the strong reference cycle warning.
I know I can go back and forth and observe that a specific class is just not leaving the memory, but wondering if Xcode is providing anything more.
- Is there any other indicator?
No, not that I know of.
- I know Xcode visually shows the number of instances of a type in memory. But is there a way to filter objects that have more than 3 instances in memory?
Again, no, not that I know of.