This workshop will be retired on May 31, 2020.
Introduction to Instruments15:15 with Gabe Nadel
Instruments is a powerful set of tools every iOS Developer needs in their repertoire. Let's take a quick tour through the areas of Leaks, Allocations and Profiles and see how we can prosecute a few real-life performance and memory issues.
It's entirely possible that you've gotten to this point in your iOS career 0:00 without ever opening instruments in Xcode. 0:03 The truth is with ARC, 0:06 most simple apps probably aren't gonna cause you performance issues. 0:07 That doesn't mean they couldn't perform better or use memory more efficiently, 0:10 just that they never exhibit symptoms severe enough to notice. 0:14 Now instruments is a very powerful tool set and 0:18 could be the subject of its own course. 0:20 Much like debugging, it's the kind of skill that you need to practice in order 0:22 to gain any sort of fluency. 0:26 So our objective here will be to show you the first level tools and tricks and 0:27 what you'll want to look for, when addressing different types of problems. 0:32 For more advanced information on instruments, I've supplied some very 0:35 useful links below and I'll call them out as they become relevant to our discussion. 0:38 So here we are inside another of Apple's sample code bases called 0:43 Lazy Table Images. 0:46 It's designed to retrieve the top app charts from the app store. 0:48 Now you and I and anyone are allowed to modify this code as we see fit. 0:51 So a friend of mine decided to do that and try and spruce it up. 0:55 After they did it though, 0:59 they said it was performing poorly, especially when they weren't on Wi-Fi. 1:00 By the way, 1:04 if you noticed this little icon up here, it indicates that I'm using a throttler. 1:05 Just like it sounds, a throttler slows something down. 1:10 In my case, I'm using it to throttle the download speed, so 1:13 I can simulate what it might be like if I weren't on Wi-Fi. 1:16 Testing apps under a throttled condition is a good habit to get into, 1:19 especially for network heavy apps, as you may experience real life conditions. 1:23 You see, if you're just testing on your home Wi-Fi or 1:27 your office Wi-Fi, you're not really getting the experience a user would get. 1:30 One app you can use for this is called slowy. 1:34 That's what I'm using right here. 1:36 It's free and you can just download it from their website. 1:38 They're also similar throttlers you can use for your devices too. 1:41 Anyway, let's run the app and see what's going on. 1:45 Okay, we see as we scroll through here, the icons are taking a while to show up. 1:51 That is not ideal, and those are just little images, 1:58 they should show up faster than that. 2:00 Okay, let's stop if for a second. 2:03 Now just because we're going to be testing this again I'm going 2:06 to delete the app itself. 2:10 So we can get a fresh try. 2:15 So now I'm gonna click this over here. 2:21 Now this is the debug navigator. 2:22 That's different than the break point navigator that you use when you debug. 2:24 Let's click the debug navigator. 2:28 Let's run it again and see what we see. 2:30 Okay, now do you notice anything? 2:34 Wow. 2:41 We're at 172 MB. 2:42 200 MB. 2:44 250 MB. 2:47 300 MB. 2:51 Over 300 MB. 2:53 That's enormous. 2:54 Over 300 MB, that's much too much for just downloading little icons and some text. 2:56 Another thin you can see here is that our memory is going up, and up, and up and 3:00 it is not coming back down really, 3:05 it is not plateauing which is what it should be doing. 3:07 When you do a repetitive task your memory shouldn't continue to climb. 3:10 Let's stop it. 3:14 And let's see what we can do. 3:17 See this debug navigator we were looking at is sort of like looking at 3:19 the dashboard on your car. 3:22 It's great to know how fast you are and if your engine needs to be checked. 3:23 But it's not great for actually diagnosing. 3:27 For that we're gonna have to dive a little deeper. 3:29 In our case, we're going to use the profiler. 3:31 It's also worth mentioning that this app is just a few hundred lines so you could, 3:34 in theory, just read through it and start looking for he issues but 3:38 even that could take a while and it wouldn't help teach you anything so 3:41 we're going to use the profiler. 3:44 To do that, you go up to product and profile but 3:46 before we do you want to check one thing. 3:49 You can go into manage schemes click on the app, go to the Profile Scheme. 3:51 Mine is already set to debug here but yours is probably defaulted to release. 3:57 You want to put it on debug. 4:02 You're going to get better information that way. 4:02 Close it up and then let's profile. 4:05 When you do that it's gonna pop up this window, 4:11 and you see you have a lot of choices. 4:13 You can look at energy diagnostics, you can look at the time profiler, 4:15 you can look at the network, you can look for memory leaks specifically. 4:19 These are all important things to do. 4:24 But to do a full lesson on the profile would be much, much longer and 4:26 we're really talking about memory management. 4:29 So I direct you to some of the links in the teacher's notes. 4:31 There's some really good stuff in there as well as our advanced debugging tutorial. 4:34 Okay, for this we're gonna pick allocations and 4:38 then we get this window which is a little too big right now. 4:42 I'm gonna re-size that. 4:45 And what we can do, let's get our reference counts there. 4:49 Check that box. 4:53 Then we just hit record and it's gonna fire up our app for us. 4:54 If we want to manipulate the app, 4:58 we can bring it to the front, scroll it around and keep your eye over here. 5:00 See those mega bytes they're just going up, and up. 5:05 We're at over 200 and that's way too much for little icons and things. 5:09 And you can see our graph here is just going up, and 5:13 up, and you can imagine if we kept doing that, the memory is just gonna go up, and 5:15 up and eventually our device is probably going to crash. 5:20 Okay I think we've seen enough. 5:24 Let's stop that. 5:26 Okay, and now we can click in here and get information. 5:29 We can also click down here. 5:31 Let's look at our stuff here. 5:34 We can see what we've allocated. 5:38 All right if you notice they are sorted by size. 5:41 I want to look at the big stuff first, 5:47 those culprits are going to be more important. 5:49 Here we've got something that's image related, it's four megabytes. 5:52 That's way too big for those little icons. 5:56 They shouldn't be four megabytes. 5:58 What's going on? 5:59 Let's click in and see what we can find out about one of these. 6:01 Drilling a little more, okay got some calls here. 6:04 Let's see if any of these means anything to us, okay? 6:08 We're allocating outlook. 6:10 All right a hash table new, hash table insert. 6:12 Now, that's gonna mean that we are inserting something to a dictionary or 6:18 to an array probably. 6:23 Now depending on what you find in here, something might be obvious to you. 6:25 You may have to start googling around, look at stack overflow, that's okay. 6:28 Using profiling doesn't usually give you the exact answer immediately, but 6:32 it gives you some really good clues to go on. 6:36 Okay, so, hash table new, and actually the insert is even more important. 6:39 Let's go looking around and see if we have an array, or a mutable array, rather, 6:45 because we're inserting our mutable dictionary, with some things going wrong. 6:48 Okay, let's look into our code. 6:53 Let's search around let's see for 6:58 mutable arrays. 7:04 We have some mutable arrays here. 7:07 We've got a cache array, got a working array, cached images. 7:09 Let's look at our cache array first. 7:19 That seems like something that could be going wrong because 7:20 our memory keeps climbing and climbing. 7:23 So we see here when we search for 7:27 cache array, it only appears here where we create the property, and 7:28 nothing is being added to it, or it would show up in this search. 7:33 So let's look for other mutable arrays. 7:35 [SOUND] And we see we have a few listed here. 7:38 Let's try cached images, that looks like it could be something. 7:43 Let's search to see where else that appears. 7:47 Okay, we got the property declaration, we have where we allocate and 7:53 initialize the array, and then. 7:57 Oh, I see. 8:02 Heather is the name of the other developer and she enhanced something here. 8:03 Well it looks like she's saying that we wanna add the app record, 8:07 icon to the cached images. 8:13 Hm. 8:17 Well it looks like something might not be going right with that caching why 8:18 it going up and up and up. 8:22 Let's comment that out, we're gonna run our code again and 8:24 see if it solve their problem. 8:27 Clean just to be sure, its profiled again 8:31 We're still getting a really, really high memory usage here. 8:55 It's much to high, still going up. 9:01 Doesn't look like we found the whole problem. 9:03 Let's stop this and go back to our code. 9:06 Let's see if Heather put in comments for the other things she might have done. 9:10 She did, very nice. 9:18 Okay, it looks like she changed the icon size here, now what does the icon size do? 9:20 Let's look at it. 9:27 Well it looks like here. 9:34 Inside of our download method, start download, it's saying if the image size 9:38 is different than the icon size, then we're going to want to do something to it. 9:43 And what we're doing here. 9:49 You're not gonna understand all of this code. 9:51 But what we're basically doing is that we're going to create. 9:53 The current image context and we are going to re-size our image. 9:56 Okay, and it looks like up top what she did was she lowered it or 10:02 rather she increased it from 48 to 1024. 10:06 That could make a big difference. 10:09 Okay let’s change that back to the way it was. 10:12 And we'll comment out her code. 10:15 And let's see what else she changed. 10:16 Okay. 10:21 Well it looks like in the download method she also is getting a hi-res icon string. 10:23 And she does that using a method here, high quality icon swap. 10:30 So let's see what that is. 10:35 We'll jump to the definition. 10:37 Yeah. Another of heather's enhancements. 10:39 So it looks like it's a method. 10:42 It takes a string as a parameter and it returns a string. 10:43 What does it do? 10:47 It substitutes the full resolution, 1024 icon. 10:48 Isn't this a great feature? 10:52 Maybe it's not a great feature. 10:54 Our app is not running well. 10:56 So I think what it does, if we want to look further, is it says, 10:58 well let's take the high res string, and that's the image URL that we get here, 11:01 and let's replace hundred by a hundred with 1024. 11:06 So we hack the URL in order to get a much bigger icon. 11:11 Now in certain cases you might want a high res icon. 11:15 But I'm not sure that this is one of those. 11:17 So we'll leave our method intact here. 11:20 We won't actually get rid of it. 11:22 But we will get rid of where it's called. 11:24 That's right here. 11:28 So instead of taking the self app record image URL string and 11:29 converting it to a high quality icon URL. 11:34 Let's copy this. 11:38 Comment this out and then we can put it in here as the URL that we want. 11:46 Okay let's give that a whirl 11:58 Didn't hit the record button, there we go. 12:10 All right, looks like we're getting a crash, what is going on here? 12:22 Oh I see, we're passing a pointer of NSString to NSURL, 12:25 we need to create an NSURL here. 12:29 I'm gonna say NSURL, URL with string. 12:31 There we go. 12:38 And now we should be okay if we add another little bracket there. 12:40 Okay, let's try that again. 12:46 Okay. 12:54 Now we see, as we scroll through our app, that our memory is around 53, 54. 12:57 We also see that if we scroll up and up and up, it goes up a little to 60. 13:02 But it's not getting up to 200. 13:08 We can scroll back down here. 13:10 And it's not getting nearly as high as it was before, so 13:13 it looks like the thing that was causing the problem was that we were 13:16 downloading a larger icon instead of a smaller one. 13:20 And then on top of that we were caching it over and 13:23 over as we scrolled through our app. 13:26 Now again, this is just an introduction, to using the profiler, and 13:29 using instruments. 13:33 Again, I encourage you to check the links below, and 13:34 it's the sort of topic that it's very difficult to learn by book studying. 13:37 You're going to have to encounter problems, do research, look at tutorials, 13:41 go back to your problems, and spend a lot of time working with a profiler. 13:45 Even when you don't see a problem with your app, it's a good idea to use this 13:49 in order to identify things that may only occur sort of on the edge cases. 13:52 But again, it's a good habit to get into. 13:57 I know it's been somewhat of a blur traveling through time from 14:00 the days when our ancestors hunted and gathered nuts, and 14:03 manually counted references on the walls of the caves they called home. 14:06 Hopefully you can breath at least a small sigh of relief knowing that you're 14:10 the beneficiary of technologies like arc and the ever growing instruments tool set. 14:13 There are two things I hope you take away from this workshop on memory management. 14:18 The first is, performance is a feature and give it the time it deserves. 14:22 Be proactive when writing code and try to eliminate memory issues, before they arise 14:27 then even if they don't arise, be sure to profile your App with instruments anyway. 14:31 It'll never hurt and you might save yourself a major embarrassment if you 14:36 catch in insidious leak or a bottleneck lurking in the shadows. 14:39 Second, if you're heading out to an interview, be sure you can speak 14:43 at least on a high level about the history of IOS memory management. 14:46 Even if you've only profiled simple swift code you should still be able to discuss 14:51 what memory management was life before ark or how you might give a closure extra 14:55 attention to prevent a strong reference cycle. 14:59 As with most things in life, practice makes perfect, so 15:02 try to make memory management a conscious part of your development going forward. 15:05 Your apps or more particularly, your users, will thank you. 15:09 Until next time, happy coding. 15:12
You need to sign up for Treehouse in order to download course files.Sign up