how XCode to calculate Memory

is there any public API or Method to get resident size of current process of game like Debug Gauges to Monitor Memory?

As far as i know someone use XCode instrument -> show the Debuger navigator -> Memory to get it, before i have found some API to get it

from internet,but a big differece bettween with the result of XCode Debuger navigator .

the first method like this:

    struct mach_task_basic_info info; 
    mach_msg_type_number_t      count = MACH_TASK_BASIC_INFO_COUNT; 

    if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)& info, &count) == KERN_SUCCESS) 
    { 
       int32_t _pss = (int32_t)info.resident_size / (1024 * 1024); 
    }

another method like this:

    task_vm_info_data_t vmInfo;
    mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
    kern_return_t kernelReturn = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
    if(kernelReturn == KERN_SUCCESS)
    {
       int32_t _pss = (int32_t) vmInfo.phys_footprint / (1024 * 1024);
    }

someone discuss:https://github.com/aozhimin/iOS-Monitor-Platform/issues/5

  1. a big differnece bettween the result of the first method and the result of XCode Debug navigator instrument, info.resident_size will not increase When the memory is allocated continuously,but xcode Debug navigator will increase.
  2. but a little difference bettween the result of the second method and the result of XCode Debug navigator instrument when use game test,but application app will same with it.


so i want to know how XCode Debug navigator to calculate Memory or how to get resident size of current process more precise,any idea will help me,thanks in advance!

Post not yet marked as solved Up vote post of aimsgmiss Down vote post of aimsgmiss
13k views

Replies

is there any public API or Method to get resident size of current process of game like Debug Gauges to Monitor Memory?

No. Calculating the memory impact of a process is a complex job and there’s no API that’s guaranteed to return the same value as the memory debug gauge.

What are you planning to use this value for? As an internal debug tool? Or something that your production app uses to guide its behaviour?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I would also need something like this, it would be used in an automated test which would measure memory footprint once finished a certain flow. So next time, if it significantly increases, we can send an email alerting about the situation.


Would it suffice to use info.resident_size ?


Thanks

it would be used in an automated test which would measure memory footprint once finished a certain flow

Cool. Using these APIs in internal tools like this is perfectly OK. I get worried when folks try to use them in their shipping app.

Would it suffice to use

info.resident_size
?

Suffice for what? Your proposed use is specific to your goals and your environment, which makes it hard for someone else to offer an opinion as to whether it’ll work well or not. Getting

info.resident_size
doesn’t require a lot of development effort (-: so why not do that and see whether it catches the problems you want to catch?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Just checking - is there yet an API available to debug builds to access the XCode memory gauge value? My intended use is to identify memory hotspots in a Unity app whose memory behavior is very different between XCode 9.4.1 and XCode 10.1. I've ruled out textures (at least textures I'm loading intentionally) as the source of this increased memory and I'm trying to narrow down which aspect of the game to investigate further.

is there yet an API available to debug builds to access the Xcode memory gauge value?

This situation hasn’t changed.

My intended use is to identify memory hotspots in a Unity app

Normally I do that sort of thing using the Instruments UI, rather than getting embroiled in the complexity of memory analysis APIs.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

My intended use is to identify memory hotspots in a Unity app whose memory behavior is very different between Xcode 9.4.1 and Xcode 10.1.

Also, just FYI, Reducing the Memory Footprint of Metal Apps.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the update!

For our app, at least since iOS 12.0, we've found that vmInfo.phys_footprint matches the memory gauge in Xcode. For better or worse, it now seems to include all of the Metal textures, etc.


We've found this to be very helpful to include in beta test logs for analyzing memory problems on user devices, since those are not observable via Xcode or Instruments. It's also helpful to record the physical memory size of the user's device available via ProcessInfo.processInfo.physicalMemory. (It sure would be great if iOS uploaded a crash log that included something useful when an app runs out of memory...)

phys_footprint
matches the memory gauge in Xcode

Yeah. Thanks for bringing this up. I should’ve mentioned it earlier, but I got lost in the minutiae )-:

The concept of footprint was introduced as an abstract representation of the general memory impact of a process, with the intention to isolate higher-level software from the gory details. You can learn more about the philosophy behind this in WWDC 2018 Session 416 iOS Memory Deep Dive. And on the Mac there’s even a

footprint
tool, with a man page.

If you’re going to record a single number, this footprint value is a good one to use. I don’t think we guarantee that it’ll align with the Xcode memory gauge, but it’s much more useful value than all the older stuff (like

resident_size
).

ps It’s deeply un-fun to call Mach APIs from Swift, so my version of this is pasted in below.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
func memoryFootprint() -> mach_vm_size_t? {
    // The `TASK_VM_INFO_COUNT` and `TASK_VM_INFO_REV1_COUNT` macros are too
    // complex for the Swift C importer, so we have to define them ourselves.
    let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
    let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size)
    var info = task_vm_info_data_t()
    var count = TASK_VM_INFO_COUNT
    let kr = withUnsafeMutablePointer(to: &info) { infoPtr in
        infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { intPtr in
            task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), intPtr, &count)
        }
    }
    guard
        kr == KERN_SUCCESS,
        count >= TASK_VM_INFO_REV1_COUNT
    else { return nil }
    return info.phys_footprint
}

Hey eskimo,


You mentioned that you shrink at the thought of people accessing these API's in a shipping application. They seem like they would be extremely useful in measuring the amount of memory that your application is currently using and avoiding large allocations that might immediately surpass a low memory warning and avoid an immediate crash.


Could you say a little more on that? What API's would you recommend using in a shipping app (where you don't have control over the size of the content you're loading in your application) to achieve this goal?


Thanks!

- Rob

What APIs would you recommend using in a shipping app (where you don't have control over the size of the content you're loading in your application) to achieve this goal?

I generally recommend that you not try to second guess the system’s memory allocator. The history of Apple platforms has many examples of where that’s proven to be a bad idea [1]. Rather, it’s better to allocate the memory you need and deal with memory warnings. The main gotcha here is that you have to rate limit your allocations, otherwise you can run into the hard limit before you have a chance to react to the memory warning.

Keep in mind that iOS limits both physical and virtual memory. Memory warnings, this footprint value, and so on, are all about physical memory usage. However, it’s not uncommon to bump into the virtual memory limit as well. There’s no equivalent to memory warnings for this limit. Rather, your allocation will just fail. This rarely affects small allocations, because

malloc
and friends suballocate, but folks regularly run into it when allocating large blocks.

If you’re dealing with arbitrary size user content then… well… that’s a really complex problem. This can cause you to hit both the physical and the virtual memory limit. The only way to guarantee success is to decouple the size of the document from the size of your memory allocations. How feasible this is depends on the document structure. For example, when dealing with a movie it’s expected that you won’t load the whole thing into memory. Likewise, image processing apps that support arbitrary size images will typically have their own mechanisms for processing the images in chunks. However, there are lots of apps where the core document code expects to load everything into memory, and there isn’t an easy solution to that problem.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Way back in the day, users of the shiny new Mac 512 found that a popular spreadsheet app couldn’t use the extra 384 KiB because the developers had hard coded for a Mac 128 )-:

memoryFootprint is quite confusing code but useful.

Putting it in the debugger and studying info (at line return info.phys_footprint) I see it has a field limit_bytes_remaining

Is this a useful guideline as to how much memory is available for allocation?

I notice that when UIGraphicsBeginImageContextWithOptions(size,....) fails with a message "Cannot allocate X bytes" X is 16 x size.width x size.height

I would like to know if UIGraphicsBeginImageContextWithOptions will fail before I call it and crash

Is this a useful guideline as to how much memory is available for allocation?

I’m glad you asked this because it’s very important that you not grab random Mach memory statistics and use them beyond their documented scope. The footprint value is a perfect example of this. It’s specifically documented as a good guide for memory usage profile, and nothing beyond that.

So, to answer your specific question, no, I wouldn’t recommend limit_bytes_remaining for this. Rather, use the dedicated API, os_proc_available_memory. See the docs here but also read the doc comments in <os/proc.h>.

Keep in mind, however, that the above is about physical memory. You also have to worry about hitting the address space limit.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

    class func availableMemory() -> size_t {
        return os_proc_available_memory()
    }

Cannot find 'os_proc_available_memory' in scope

Is there a version I can access from Swift?

Well, that’s annoying. It seems that <os/proc.h> is not listed in the Darwin module map and thus isn’t imported into Swift. I’d appreciate you filing a bug about that. Please post your bug number, just for the record.

On the workaround front:

  • If you’re building an app, add the following to your bridging header:

    #include <os/proc.h>
    
  • If you’re building non-app code you’ll need to wrap this in your own Objective-C code and then use that from Swift.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"