Instruments: Leaks and Allocations (tvOS)

2019-07-30 01:37发布

问题:

I’m currently working on a tvOS app. This is my first native (Swift) app. The app will be a digital signage app, used during events or in offices of companies. One big difference compared to a typical app on iOS/tvOS is that it needs to run pretty much 24/7, so memory is a big topic for this app. The smallest leak will eventually cause the app to crash.

The app is constantly looping through a set of fullscreen slides. At the bottom of the screen there is a ticker with 10 articles (refreshed every 10 seconds - now during development). Below is a screenshot of the weather slide, to get an idea.

Currently the app is crashing after a period of time and I’m pretty sure I’ve narrowed it down to the ticker component (when disabling it, the app lives for days). If I use the ‘Leaks’ preset in Instruments I get the following result:  It looks like it’s leaking Article instances. I’m recreating Article instances every 10 seconds and providing them to the ticker component. I think that is why new instances leak every ~10 seconds.

Before I started using the ‘Leaks’ preset in Instruments, I used the ‘Allocations’ preset, while using this all seemed fine to me. But I’m probably misreading the results…

Using allocations:  The way I read this is that currently 10 Article instances exist in memory, and 31 have existed but are cleaned up now - so I’m safe.

But the app still crashes.

I’ve read a lot on retain cycles, implemented weak/unowned where I believe I should.

So my question is not so much about code, but more about how to read this data, what does a Leak mean in this context, and why do I see these ‘leaks’ not as persistent objects in the Allocations window?

(tests are done on multiple devices + simulator)

回答1:

If you see a steady (i.e., approximately n GB / minute or hour) increase in memory usage in Instruments, that is a good sign that objects are being created, but not dealloced. Your allusion to weak and unowned vars makes me think that you know this, but you may not have found all sources of your leak. I would suggest taking a few generation summaries in Instruments, and looking at specific classes/objects in Heap allocations. Your problem classes will steadily increase in number, and likely never decrease. Try to debug the problem from there.

As for what 'leak' means in this context, it's what it always means: Your computer is not releasing memory resources. It may seem different, because we are used to thinking of a leak as something that eats through memory at a much faster rate (like an infinite loop running on four cores, or something), but that kind of leak and this are actually the same thing; yours is just slower.



回答2:

I’m back after weeks trying to figure out what was wrong. The good news, I found my leak, and solved it!

The issue was solved by removing a closure inside another closure keeping a reference to a variable in the first closure. This caused a retain cycle.

I really don’t understand why I didn’t find it earlier, I asked a new question for this here: getting-different-data-in-instruments-based-on-method-of-profiling.