I Profile my Xcode app using Allocations from Instruments and everything looks fine as far as All Allocations Live Bytes is sitting right around 7 MB. I execute a routine and the Live Bytes jumps (or declines?) to - 6 GB? Yes that's GB and it's negative?
Xcode 4.6.2
Instruments 4.6
Related
I have an x86_64 macOS app that according to Activity Monitor, it uses between 35 to 50MB of memory with an Intel MacBook Pro. When I run the same app in an M1 MacBook Pro with Rosetta, it shows 2.5 to 3x more memory in Activity Monitor.
I then updated the app in my M1 to both x86_64 and arm64, and run it again. In the Intel MacBook Pro it uses 40 to 60MB in Activity Monitor. In the M1, Xcode still shows the 3x increase in Memory Report and Activity Monitor.
In the M1, from Memory Report I clicked Profile in Instruments and it shows the heaviest stack trace is in system libraries, specifically this one:
46 AppKit 183.46 MB +[NSBundle(NSNibLoading) loadNibNamed:owner:]
See the image and the call tree all the way down to mmap:
However, when I try to profile the app again in my M1 but directly from Instruments > Allocations, it shows the regular 35-50MB memory usage, nothing more. [NSBundle(NSNibLoading) loadNibNamed:owner:] is not taking all the memory as above. Here is an image:
The only graphics the app has are a couple of storyboards with some custom Core Graphics code for custom drawings. I'm on Big Sur 11.2 and Xcode 12.4.
My understanding of memory usage using Instruments is basic, so my questions are:
What could be happening here with the different memory usage between M1 vs Intel, and between Instruments and Instruments running from Memory Report?
Why is all the memory going to this NSBundle(NSNibLoading) loadNibNamed:owner:]?
How can I reduce the memory usage for the M1?
Thanks for any help!
If you want to see how much memory your app is using, look at the Persistent Bytes column for the All Heap Allocations category in the Allocations instrument. Note that this category does not include texture memory.
To make it easier to find the code that allocates the most memory, click the Call Tree button at the bottom of the Instruments window and select the Invert Call Tree and Hide System Libraries checkboxes. The following tutorial provides a detailed explanation on using Instruments to measure memory usage:
Measuring Your App's Memory Usage with Instruments
I am working on a mail client on iPad (similar to that of the default app client) and using core data framework as a cache to increase performance . My app uses around 4.5 - 5 MB of heap memory and then it crashes because of memory overflow (detected this using allocation instrument). If I try to reduce memory my performance becomes very slow and sluggish because I am not able to cache my views, data structure (which store folders and all the mails) and tableviews.
I have checked my crashLogs and I see jettisoned written in front of my App which confirms that OS has forcefully closed my App!
I have used instrument to detect these limits. Please find the attached image here
This is a snapshot my recordings just before the app crashes.
I have tested my app on simulator and it stabilizes itself at 6 - 7 MB of heap memory.
Is there any way so that I can ask OS for more memory or avoid crash with a little redesign in my code.
Any suggestions or help would be highly appreciated.
6-8MB of memory should never be a problem. Likely you are either trashing memory or if you are running a debug version and have Zombies turned on, the default is to never delete the zombies. NSZombiesEnabled=YES and NSDeallocateZombies=NO will appear to leak memory as nothing is ever deleted.
When profiling my app with Instruments (looking for memory leaks), I get extremely different results with the iOS 5 iPhone Simulator from those I get with my iPhone 4 running iOS 5. The first picture shows the results from the profiling with the real device, and the second is with the simulator:
Real device:
iOS 5 Simulator:
This profile is taken up to the same point in the app in both cases: completion of viewDidLoad in the rootViewController's view lifecycle. I have waited in both of them for the total allocated memory to stable out. As you can see in the device graph, there are some extreme fluctuations occurring at about 00:10, which aren't present in the Simulator. On the real device, total allocated memory, at around 00:08, jumps from 1MB to 3.5 MB then back down to 1.5 MB and finally jumps to 4.74, where it stabilizes. The allocated memory for the Simulator is much more linear, with it climbing steady and quickly to around 2.35 MB where it stabilizes.
Another thing to note is the presence of 2.25 MB of allocated memory present on the device but not the Simulator from malloc and 700+ KB from CFNumber. As I am relatively new to using Instruments and profiling, I'm not exactly sure if this is normal. A quick Google search turned up nothing definitive. That 2.25 MB and 700 KB more than make up for the difference in memory allocation. To balance things, there are more entries for malloc with different amounts of memory present in the Simulator test not present in the device test.
Also, I found that when a second UIViewController is pushed onto the UINavigationController stack, allocated memory jumps to about 8.5-9 MB on the real device, but only about 4.5 to maybe 4.5 megabytes tops on the Simulator.
I know it is to be expected that the device would perform much differently from the Simulator, but should memory allocation not be pretty similar because the same code is being run on both devices? I would understand if this is a performance profiling, but for memory allocation, it seems that the numbers should be pretty similar. Can anyone shed some light as to whether this is normal or not?
This behavior is to be expected. Technically, when you run profiling with the simulator you are measuring stats based on your desktop's hardware. Even if you're just profiling allocations you can't expect them to work similarly because a lot of software optimizations/algorithms/etc are based on the hardware it's running on.
Unfortunately, Apple doesn't have an iOS emulator. You're better of profiling with the device though, as emulators tend to still be unreliable and slow (e.g. Android emulator).
You should always run leaks on an iOS device and never on the simulator. The results you get from the simulator will only serve as a distraction since they are rarely 100% accurate. You'll find yourself chasing down a lot of red herrings! hehehe
I know it is to be expected that the device would perform much
differently from the Simulator, but should memory allocation not be
pretty similar because the same code is being run on both devices? I
would understand if this is a performance profiling, but for memory
allocation, it seems that the numbers should be pretty similar. Can
anyone shed some light as to whether this is normal or not?
Technically the code is completely different. The simulator application compiles for x86 bytecode, while the device compiles for armv6/armv7.
What is the amount of memory an app can take before getting kicked by iOS?
Does the amount of memory depends on the device version?
I have developed an app which is using 30+ mb and its getting kicked on iPhone 2g. Can it work on iPhone 4 or 3GS?
My experience with the iPhone 3G is that you should try to stay as small as humanly possible--build your data model with ditchability in mind, because you'll need to ditch. 20mb is bumping against the limit. 25 MIGHT be okay if the phone has been rebooted recently. You'll probably never get 30mb.
By contrast... I managed to prompt a memory warning on my iPhone 4 once, but it was due to an infinite loop bug that downloaded the same image file an infinite number of times. In other words, it took something REALLY drastic to crush the 4. Not that you can ignore memory management completely (a leak is still a leak), but for sure you've got some breathing room.
The 3Gs is somewhere between the two. I don't have one to test on, but I'd expect its performace is more 4-like than 3G-like, because while the on-board memory doubled from the 3G, the OS is still taking up the same space, meaning all of the new memory is yours to play with.
All your application's resources on an iPhone 2 should probably stay at less than 20 MB. You can go a little over, but that's it, otherwise the memory warnings will occur. There's only 128 MB of total physical ram for everything - that's the OS as well as your own app.
Is Activity Monitor (a.k.a. Memory Monitor) the only tool in Xcode Instruments that can measure the total app RAM usage of an iPhone app running in Simulator? Just that line showing momentary wired RAM?
And how accurate is that versus iPhone hardware, especially given OSX paging i/o to VM?
I'm seeing 7-8MB wired RAM figures for just the default Xcode iPhone project templates (other than OpenGL) compiled and running. At the same time Object Allocations shows well under 1MB for all objects.
Nope, there's a much better way to do it.
Go to the Run menu and select Run with Performance Tool then Object Allocations.
This will start Instruments and will show RAM usage. It's also useful for detecting memory leaks if you choose Leaks instead of Object Allocations.
I would agree, since the Simulator is just an "API simulator", the behavior you see is going to be at least somewhat dependent how OS X manages memory. And the restrictions are obviously different, for example you can exceed 128 MB of ram, or even 256 MB, which obviously isn't possible on any current iPhone or iPod Touch (at least, as of this writing...).
I've still found it useful in OpenGL for making sure textures and other items are properly deallocated, but beyond that, it's just a rough guideline.
However, if you want to see memory usage on device, there's a simple enough solution. Just target Device in Xcode, and go to Run > Run with Performance Tool > Object Allocations, then the build will be sent to the device and the Object Allocations tool will pop up next to Xcode and show on device memory usage.