Under what conditions can an iOS app exceed its memory footprint limit and continue running?

I would like to understand the relationship between an iOS app's memory footprint and the memory limit used by os_proc_available_memory().

Device: iPhone 15 Pro Max (iPhone16,2).
The reported OS is iOS 18.5 (22F76), but the accompanying diagnostic metadata lists iOS 17.5.1 (21F90). The OS version for this incident is not yet confirmed.

This was a very rare occurrence. We do not have reliable reproduction steps.

In the first 26 recorded samples, footprint + os_proc_available_memory() is approximately 6,442,450,944 bytes (6 GiB). In the final four samples, os_proc_available_memory() is 0, but footprint continues to increase.

From the first zero-available-memory sample to the last sample:

  • Elapsed time: 2.928 seconds.
  • Footprint: 6,510,375,920 to 7,245,821,920 bytes.
  • Additional footprint: 735,446,000 bytes (735.446 MB).

Questions:

  1. Why could the app continue allocating memory after its footprint exceeded the apparent memory limit, with footprint continuing to increase for the interval shown above?
  2. The os_proc_available_memory() documentation says the function returns 0 if the process has already exceeded its memory limit. Under what circumstances can a process exceed that limit and still continue running and calling this function?
  3. The documentation also says memory limits can change during the app life cycle and do not necessarily correspond to the physical memory available on the device. What specific conditions cause this limit to change?

Documentation: https://developer.apple.com/documentation/os/os_proc_available_memory

All 30 samples are below. Timestamps are Unix milliseconds; both memory columns are in bytes. Commas within numbers are thousands separators.

timestamp_ms      | footprint (bytes) | os_proc_available_memory (bytes)
1,793,468,915,891 | 2,107,497,360 | 4,334,953,584
1,793,468,916,891 | 2,035,637,136 | 4,406,813,808
1,793,468,917,891 | 1,931,844,544 | 4,510,524,480
1,793,468,918,891 | 1,311,349,696 | 5,131,101,248
1,793,468,919,891 | 1,310,268,352 | 5,132,182,592
1,793,468,920,891 | 1,297,144,768 | 5,145,306,176
1,793,468,921,891 | 1,315,003,328 | 5,127,447,616
1,793,468,922,891 | 1,330,895,856 | 5,111,489,552
1,793,468,923,891 | 1,783,930,080 | 4,658,504,480
1,793,468,924,891 | 2,133,515,728 | 4,308,836,912
1,793,468,925,891 | 2,441,863,040 | 4,000,571,520
1,793,468,926,891 | 2,710,790,352 | 3,731,611,440
1,793,468,927,890 | 3,127,452,336 | 3,314,933,072
1,793,468,928,890 | 3,348,341,760 | 3,093,961,728
1,793,468,929,891 | 3,573,834,992 | 2,868,615,952
1,793,468,930,891 | 3,918,456,384 | 2,523,879,872
1,793,468,931,891 | 4,149,520,272 | 2,292,815,984
1,793,468,932,891 | 4,449,937,680 | 1,992,513,264
1,793,468,933,891 | 4,729,449,104 | 1,713,001,840
1,793,468,934,891 | 4,902,857,600 | 1,539,478,656
1,793,468,935,891 | 5,146,340,608 | 1,295,733,504
1,793,468,936,891 | 5,348,453,920 | 1,093,997,024
1,793,468,937,891 | 5,625,376,624 | 816,976,016
1,793,468,938,891 | 5,820,412,000 | 621,580,192
1,793,468,939,891 | 6,099,595,696 | 342,855,248
1,793,468,940,891 | 6,284,112,592 | 158,272,816
1,793,468,941,963 | 6,510,375,920 | 0
1,793,468,942,890 | 6,765,426,032 | 0
1,793,468,943,891 | 7,088,387,872 | 0
1,793,468,944,891 | 7,245,821,920 | 0
Answered by DTS Engineer in 914014022

These two numbers are not meant to be correlated. Rather:

  • os_proc_available_memory is intended to be used by your app to guide its memory usage at runtime. The doc comments in <os/proc.h> explain this in detail.
  • The footprint value is intended to be used by memory profiling tools as single number that reasonably represents your app’s memory impact.

Given that, the behaviour you’re seeing does not come as a surprise.

Written by yongpengliang in 854762021

What specific conditions cause this limit to change?

That’s not documented, and deliberately so. These are implementation details that can and do change on a regular basis.

If you explain what problem you’re trying to solve with these numbers, I might be able to offer you more specific advice.


Also, I think you should have a read of On Free Memory. It doesn’t address your questions directly, but the example it describes should help you understand why the questions you’re asking don’t have API-level answers.

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

These two numbers are not meant to be correlated. Rather:

  • os_proc_available_memory is intended to be used by your app to guide its memory usage at runtime. The doc comments in <os/proc.h> explain this in detail.
  • The footprint value is intended to be used by memory profiling tools as single number that reasonably represents your app’s memory impact.

Given that, the behaviour you’re seeing does not come as a surprise.

Written by yongpengliang in 854762021

What specific conditions cause this limit to change?

That’s not documented, and deliberately so. These are implementation details that can and do change on a regular basis.

If you explain what problem you’re trying to solve with these numbers, I might be able to offer you more specific advice.


Also, I think you should have a read of On Free Memory. It doesn’t address your questions directly, but the example it describes should help you understand why the questions you’re asking don’t have API-level answers.

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