I have a huge synchronization process in which I download and unzip 400-500 XML files and then parse it. With this data Im going to create a lot of core data objects over the RestKit API. At the beginning, I had a memory warning with live bytes of 450mb+ because I did not using autorelease pools and only tried to save core data on the end.
I fixed that, saving now frequently to core data and using #autoreleasepool blocks. When im running my app now with instruments, I can see how the live bytes only being 20mb-30mb, always releasing memory and never going to size up. The process just works. But when I start the app without instruments, after a view files I get a Memory Warning. Later on the app crashs.
What is the differene between running the app with and without the instruments tool? Why does it end in different results?
I'm adding this answer because I'm so happy that I came across this page.
What #borrrden suggested is partially true. You can configure which Build settings it will use when you profile. To configure this, goto Xcode and open the Edit Scheme dialog and select in the left menu Profile XXX.app. You will see you can choose a Build Configuration (either Debug or Release).
What #hooleyhoop commented was more crucial to find the solution. Even if your Profile Build Configuration is set to Debug, there is still a difference between Profiling and a default Run from within Xcode. You can specify Diagnostics in the Run section. Right there, there is an option called Enable Zombie Objects under Memory Management. Make sure that this option is unchecked.
These diagnostic Run settings are not used while profiling. That is the explanation for the behavior you are experiencing. There isn't a Diagnostics tab on the Profile section as well.
The result is that my game (Gump) crashed after 5 minutes of doing nothing in the main menu with Zombie Objects enabled. Once I disabled Zombie Objects, my game runs as far as I know for an infinite amount of time. After 45 minutes, still no Memory Warnings.
Related
My app seems to have a memory problem. I'm not getting any crashing, but when testing on device, both Instruments and the Debug Navigator agree that the amount of memory my app is using keeps increasing depending on what I'm doing in the app.
So, I tried to diagnose the problem.
First, I thought about normal memory leaks -- and there were many. So, after a lot of work with the Instruments -> Leaks template, I was able to eliminate them.
But the memory problem persisted.
So, I decided to look for zombie objects. First, I enabled zombies in Xcode. Because I was unsure whether I needed to enable zombies for "Run" or "Test" or both, I did both. So, that's Edit Scheme -> Run -> Diagnostics -> Zombie Objects and Edit Scheme -> Test -> Diagnostics -> Zombie Objects.
I was also unsure whether to run Instruments through a debug or release build configuration, so I tried it with both (with the same outcome).
Here's a screenshot showing the location of the Debug Navigator:
Here's a screenshot of the memory options I enabled prior to using View Memory Graph Hierarchy:
Now that zombies are enabled, I go to Debug Navigator -> View Memory Graph Hierarchy, and Xcode builds a memory graph that says my app has something like a thousand zombie objects. There are zombies of all kinds -- everything from SceneKit stuff to CloudKit and GameplayKit stuff.
Here's a screenshot of some of those zombie objects:
So, I decided to investigate further using Instruments.
Here's what Apple says on using Instruments to detect zombies:
"If a call is made to a deallocated object, a flag is inserted in the
timeline pane and a Zombie Messaged dialog appears, indicating that a
message was sent to a deallocated object at a specific memory
address."
However, if I open Instruments and use the Zombies template, I never see any such flags/dialogs.
Here's a screenshot showing what I see after running the Instruments Zombies template (notice the lack of flags/dialogs):
Question: Why might the memory graph hierarchy tool and Instruments disagree so markedly on the presence of zombies? Is there some further Xcode configuration I'm missing or something? How should I proceed?
Thanks!
I'm using XCode 7.0 with iOS 9.0 SDK & ARC, all profiling/testing done on an iPhone 5S with iOS 9. EDIT: for all screenshots, it was a single run: I ran a debug build straight from xcode, and then manually attached Instruments to it. So the screenshots are all from the exact same single test run. This memory growth (per xcode view) is 100% reproducible.
My app downloads ZIP files, unpacks them, and adds them to the camera roll. I've made sure to profile and catch memory leaks (ie. missing CGContextRelease) as well as using #autoreleasepool etc
During unzipping, in xcode I see the memory usage shooting up fast, never-ending until the unzipping finishes, and I cannot explain this because there are no objects in Instruments that I can see being held onto. The memory is never released (per xcode's memory view). At the end of my test run I see 236MB used, with no memory warnings during unzipping. If I use Instruments' allocation tool, I see 50.2MB of heap and anonymous VM used. That's a huge difference!
The first thing I did was assume that [UIImage imageNamed:was to blame (caching etc) because I have quite a few animated UIImageViews, so I spent time removing all imageNamed from my code, and using imageWithContentsOfFile instead. That didn't help at all. I add the unzipped images to the camera roll with iOS 8 Photo framework like this: [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:[NSURL fileURLWithPath:filePath]]
I've spent considerable time pouring through Instruments and web articles but to no avail. Can anyone answer these questions?
Why the discrepancy between xcode memory usage & Instruments -- is this normal?
I assume that these numbers are too high for releasing such an app, and I have to improve this before I upload to app store, right?
Looking at the screenshots below can you make any suggestions where I could start looking for the problem(s)?
Thank you very much in advance for your help. Of course i'll post any source-code that would help, i'm just not sure where to begin...
XCODE MEMORY USAGE 236 MB
INSTRUMENTS
The most common cause of this is your configuration. By default when you run in Xcode, you build in Debug mode. When you profile in Instruments, by default, it builds Release. You can modify your Run and Profile configurations in your scheme to change this.
I'm using XCode 7.0 with iOS 9.0 SDK & ARC, all profiling/testing done on an iPhone 5S with iOS 9. EDIT: for all screenshots, it was a single run: I ran a debug build straight from xcode, and then manually attached Instruments to it. So the screenshots are all from the exact same single test run. This memory growth (per xcode view) is 100% reproducible.
My app downloads ZIP files, unpacks them, and adds them to the camera roll. I've made sure to profile and catch memory leaks (ie. missing CGContextRelease) as well as using #autoreleasepool etc
During unzipping, in xcode I see the memory usage shooting up fast, never-ending until the unzipping finishes, and I cannot explain this because there are no objects in Instruments that I can see being held onto. The memory is never released (per xcode's memory view). At the end of my test run I see 236MB used, with no memory warnings during unzipping. If I use Instruments' allocation tool, I see 50.2MB of heap and anonymous VM used. That's a huge difference!
The first thing I did was assume that [UIImage imageNamed:was to blame (caching etc) because I have quite a few animated UIImageViews, so I spent time removing all imageNamed from my code, and using imageWithContentsOfFile instead. That didn't help at all. I add the unzipped images to the camera roll with iOS 8 Photo framework like this: [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:[NSURL fileURLWithPath:filePath]]
I've spent considerable time pouring through Instruments and web articles but to no avail. Can anyone answer these questions?
Why the discrepancy between xcode memory usage & Instruments -- is this normal?
I assume that these numbers are too high for releasing such an app, and I have to improve this before I upload to app store, right?
Looking at the screenshots below can you make any suggestions where I could start looking for the problem(s)?
Thank you very much in advance for your help. Of course i'll post any source-code that would help, i'm just not sure where to begin...
XCODE MEMORY USAGE 236 MB
INSTRUMENTS
The most common cause of this is your configuration. By default when you run in Xcode, you build in Debug mode. When you profile in Instruments, by default, it builds Release. You can modify your Run and Profile configurations in your scheme to change this.
I've been running into a problem with Apple Instruments (4.6, Xcode 4.6.2 on 10.8.3).
Normally when using the Time Profiler, I can look at my source and see the hotspots without any problems (same project).
This time I've been trying to use the "Counters" Template to sample my CPUs Performance Counter Events. It samples the events as it should and I also have the same time based profiling information as well, however when I try to step into my code to look at the hot spots, like I can do for the "Time Profiler", all I get is "Unavailable" where I used to have the source. No Assembly either.
The Project is built as:
Release build
Debugging information is on and not stripped
DWARF + dsym is used to store the profiling data.
As I said, its the same configuration that works for the time profiler.
I already tried to (pretty much all that's stated in here: Xcode 4 Instruments doesn't show source lines , except for doing -O0, debug performance is not of interest to me)
recompile
relocate the dysm file using "File -> Re-Symbolicate"
As soon as I plainly close Instruments, start another Profile from Xcode and choose the Time Profiler, it works, if I go back to the Performance Counters, it stops.
Is this the default behaviour? Should it be like this? Has anybody already managed to get it working, in the current Instruments version? Otherwise it might be worth to file a bug with Apple.
Thanks a lot!
Try the Xcode 5.1 beta4. For me its fixed there: Counter works now.
The seed notes mentions some details what they did. Don't know if its under NDA.
I'm trying to optimize the memory usage of an iOS app, and I'd like to see what the app's total memory usage is at specific points in the code. I was thinking I should be able to set breakpoints, profile the app with Activity Monitor, and just look at the memory use when each breakpoint catches. But when I run Instruments, it seems breakpoints no longer stop execution, so it's hard to know exactly when memory usage is changing.
Is it possible to use breakpoints and Instruments at the same time? If not, is there a clever way of writing some code to insert a marker into the Instruments timeline when specific events occur?
I also ran into this issue today, and after a bit of searching I found this solution. Text below is a quote from the post:
Breakpoints Do Not Break. Instruments utilizes debug information from
your debug build, however, it does not stop at break points you set.
This is because while you are loading your application into
Instruments from the menu in XCode, Instruments simply uses the path
of the current executable as its start path and loads it externally
from XCode. The menu in XCode is really there as a convenience
mechanism. This is not a big deal as you can always run again in Debug
mode after your instruments session should you want your application
to break. It’s just something to make a note of.
NSLog Statements Do Not Show In The Debugger Console. If you want to
see your NSLog statements, you will need to load the system Console
application (/Applications/Utilities/Console).
Reference: http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/
Well, you aren't running under control of the debugger.
One approach might be to add alerts at the key points, and take a heapshot then (manually).
Or there may be some dtrace wizardry.