Different memory usage with macOS app between an M1 and Intel MacBook Pro - swift

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

Related

Profiling memory leaks with Instruments- huge difference between iPhone 4 and iOS 5 Simulator

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.

Memory Management/Instruments on the iPhone

I'm developing an RSS reader type iPhone application and it is nearing completion, however I upgraded to Xcode 4 with iOS 4.3 yesterday and I have run into some serious memory issues. My App now frequently gets memory warnings, I'm handling didReceiveMemoryWarning, and releasing all my cached images etc, but this does not provide a good user experience. I've also been using Instruments in an attempt to diagnose the problem, but this has been bringing up more questions then answers.
• Does the SDK 4.3 use more memory ? I wasn't receiving memory warnings before I upgraded. Not sure if this is relevant or not, but I'm doing most of my testing on an iPhone 3G with iOS 4.2 on it (4.3 is not supported on a 3G).
• Why does the allocations instrument tool live bytes column not match the real memory column in the activity monitor tool ? The activity monitor tool always reports more memory usage.
• According to leaks my app does not leak memory, in the simulator or on an actual iPhone, but when I look at allocations, it seems that as I transition between views and then pop views, the live bytes column does not return to its previous value, which is consistent with leaking memory ? (Yes subviews are released after they are popped)
• My app frequently reports a memory warning on startup, but only when I'm profiling the application with leaks. Does leaks cause extra memory overhead ?
• Perhaps this is a difficult question to answer, but what is a reasonable memory footprint for an iPhone app ? When I'm running leaks, my app will almost certainly be killed due to low memory a few minutes into being run, but allocations in the leaks tool reports I'm using less then 2 MB when the app is terminated.
• Why does the activity monitor instrument have a column for virtual memory ? Everything I've read states that the iPhone does not utilize virtual memory ?
The 4.3 SDK probably does use more memory, but if that's a question you're asking then you're probably on the wrong track, because as a developer that should not factor into how stable your app is.
I would not worry about the discrepancy between what Allocations reports and what Activity Monitor reports. It is also not unusual for the memory footprint to grow, as views are pushed and popped, and not shrink. Another answer on how free(3) works explains this phenomenon in better detail.
A reasonable memory footprint for an iOS app is the lowest amount your app needs in order to function.
iOS does indeed use virtual memory. From Apple's Memory Usage Performance Guidelines / About the Virtual Memory System:
Both Mac OS X and iOS include a fully-integrated virtual memory system that you cannot turn off; it is always on. Both system also provide up to 4 gigabytes of addressable space per 32-bit process.
...
Although Mac OS X supports a backing store, iOS does not. In iPhone applications, read-only data that is already on the disk (such as code pages) is simply removed from memory and reloaded from disk as needed. Writable data is never removed from memory by the operating system. Instead, if the amount of free memory drops below a certain threshold, the system asks the running applications to free up memory voluntarily to make room for new data. Applications that fail to free up enough memory are terminated.
I recommend you read through the whole document, especially Finding Memory Leaks. You can also use the Build-and-Analyze feature, which uses the built-in Clang to statically detect several kinds of bugs, including memory leaks.

XCode and Instruments: How to get the app memory peak

I'd like to show the memory peak (not 'leak', but the highest quantity of memory used in small amount of time) of an iPhone app i am running in the simulator. Where shall i look precisely?
PS I am using libxml2 and i suppose that the allocations done by the library aren't considered
Use the "Allocations" performance tool by selecting Run | Run with Performance Tool | Allocations in Xcode. This will show you everything that your app allocates including items in libxml2. You may not to see exact line numbers of memory allocations in the library, but you will be able to see where the majority of your allocations are happening.

How much memory is my iphone app using (from Simulator)

I know this has something to do with Instruments, but well it's kind of confusing and searching for Instruments on Google doesn't help much.
I'd like to know how well my app runs, like how much memory it uses. I just don't know where to find something like:
"As close as we can tell from the simulator you'll app will currently be using xx MBs of RAM on a real iphone device."
I need help on how to get this information.
You shouldn't test your memory usage in the simulator for a number of reasons, some of which are:
The simulator is running on your computer, not the phone, so the maximum amount of memory is the same as the amount of ram you have installed in your Mac.
The simulator, and your app when build with the simulator SDK, do not use the same libraries as they would on the device, and as a result, could use a different amount of memory.
However, if you can run on a device, you should use the Memory Monitor and Object Allocations instruments in Instruments to monitor your memory usage.
You should use the Run/With Performance Tools/Object Allocations. The graphs will show you the memory used.
And then you check the box "Created and Still Living" to know what objects are in memory.

Xcode Instruments: peak RAM of iPhone apps running in Simulator?

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.