Increased Memory Limit for QL Preview Generator

we have written a QL preview generator for some 3D data formats not supported by the AR Quicklook generators included in iOS.

however, we are struggeling with the 100 MB memory ceiling imposed on an app extension in iOS.

we have included the "Increased Memory Limit" entitlement in both the app and in the preview extensions.

nevertheless, the preview generator is limited to 100 MB, even on most recent devices like iPhone 16 Pro Max. we can even see 100 MB limit when we attach to the process with Xcode.

my question: did we miss anything? are there additional steps necessary to obtain the increased memory limit? must we explicitly apply for it? 500 MB would be fine (our preview generator does not load textures).

best regards

Answered by DTS Engineer in 840353022

however, we are struggeling with the 100 MB memory ceiling imposed on an app extension in iOS.

The full details on why are below, however, the only concrete advice I can really offer here is:

  • File bugs describing WHY you need the additional memory and asking the system wide limit to be increased.

  • Find ways to live within the limit.

my question: did we miss anything? are there additional steps necessary to obtain the increased memory limit?

No, what you're seeing is the expected behavior. The short summary is that every extension point defines it's own memory limit and that memory limit overrides the value that the "Increased Memory Limit" entitlement modifies. Strictly speaking, your extension applied to it, but that didn't matter because the hard limit supersedes that value.

The longer explanation here is that what you're asking for here is a very bad idea when it comes to overall system stability. Architecturally, there has always been a tension between:

  1. App being allowed to use the "maximum" possible memory.

  2. App crashing all that time because the systems state changed.

At the same time, both total device memory AND total possible background activity has increased. That dynamic means that, over time:

  • The absolute maximum amount of memory an app could (theoretically) use has greatly increased.

AND

  • The range of possible simultaneous background activity has greatly increased the range of memory "swings" that become possible.

Putting that in concrete terms, consider the difference in memory available to the foreground between:

(1) The app is running in the foreground as the "only" app.

AND

(2) The app is running in the foreground while the user is:

  1. Switching between the voip calls of two different voip apps

  2. Listening to music (not every call is THAT interesting...)

  3. Receiving a stream of notifications

  4. Watching a video using picture in picture (Did I mention that one of those calls was a video call...)

  5. Add what other random activity you can think of...

That can quickly eat up a lot of memory and, critically, most of the stuff in that list has HIGHER priority than the foreground app. SO, in a world where we actually allow the foreground app access to "all" available memory, what actually ends up happening is that apps start dying more often because they work fine in the simple case (#1) and fail terribly once things get complicated (#2). Even worse, testing #2 is difficult and error prone, since it's hard to know how much activity is "to much", particularly between different devices.

SO... That's not how the system works. Greatly oversimplifying, how things generally work is:

  • A certain amount of memory is set aside so that "basic" foreground apps always work fine.

  • A small amount of memory is set aside so that it's a certain amount of critical background activity is ALWAYS possible.

  • A bunch of other limits and heuristics are then applied to try and balance the needs of critical background apps/work against their ability to disrupt the foreground app and each other.

  • There's a large amount of "extra" memory which could be used for background or foreground work (depending on how the device is being used).

This allows the system to provide the foreground app with plenty of memory while still ensuring that some amount of background work is always possible. All of that is what helps provide a relatively consistent user experience even as the type and volume of device activity changes over time, devices, and users.

With all that context, let me jump back to what I said here:

"....every extension point defines it's own memory limit and that memory limit overrides the value that the "Increased Memory Limit" entitlement modifies."

The reason extension points each define their own limit is because the focus of the extension point system is on allowing lots of small components to run simultaneously. The more memory an app extensions uses, the more often we'll inevitably be forced to either:

  • Terminate the app extension (because other, critical, work must occur).

  • Terminate other work (because the app extension is "more" important).

...expanding exactly the problems we're trying to address.

must we explicitly apply for it?

No. At a purely technical level, I don't think it's actually possible for the system to grant your app extension more memory. The hard limit was applied when launchd created your process and that limit came from a hard coded list of app extension types. I'm not aware of any mechanism that would bypass that.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

however, we are struggeling with the 100 MB memory ceiling imposed on an app extension in iOS.

The full details on why are below, however, the only concrete advice I can really offer here is:

  • File bugs describing WHY you need the additional memory and asking the system wide limit to be increased.

  • Find ways to live within the limit.

my question: did we miss anything? are there additional steps necessary to obtain the increased memory limit?

No, what you're seeing is the expected behavior. The short summary is that every extension point defines it's own memory limit and that memory limit overrides the value that the "Increased Memory Limit" entitlement modifies. Strictly speaking, your extension applied to it, but that didn't matter because the hard limit supersedes that value.

The longer explanation here is that what you're asking for here is a very bad idea when it comes to overall system stability. Architecturally, there has always been a tension between:

  1. App being allowed to use the "maximum" possible memory.

  2. App crashing all that time because the systems state changed.

At the same time, both total device memory AND total possible background activity has increased. That dynamic means that, over time:

  • The absolute maximum amount of memory an app could (theoretically) use has greatly increased.

AND

  • The range of possible simultaneous background activity has greatly increased the range of memory "swings" that become possible.

Putting that in concrete terms, consider the difference in memory available to the foreground between:

(1) The app is running in the foreground as the "only" app.

AND

(2) The app is running in the foreground while the user is:

  1. Switching between the voip calls of two different voip apps

  2. Listening to music (not every call is THAT interesting...)

  3. Receiving a stream of notifications

  4. Watching a video using picture in picture (Did I mention that one of those calls was a video call...)

  5. Add what other random activity you can think of...

That can quickly eat up a lot of memory and, critically, most of the stuff in that list has HIGHER priority than the foreground app. SO, in a world where we actually allow the foreground app access to "all" available memory, what actually ends up happening is that apps start dying more often because they work fine in the simple case (#1) and fail terribly once things get complicated (#2). Even worse, testing #2 is difficult and error prone, since it's hard to know how much activity is "to much", particularly between different devices.

SO... That's not how the system works. Greatly oversimplifying, how things generally work is:

  • A certain amount of memory is set aside so that "basic" foreground apps always work fine.

  • A small amount of memory is set aside so that it's a certain amount of critical background activity is ALWAYS possible.

  • A bunch of other limits and heuristics are then applied to try and balance the needs of critical background apps/work against their ability to disrupt the foreground app and each other.

  • There's a large amount of "extra" memory which could be used for background or foreground work (depending on how the device is being used).

This allows the system to provide the foreground app with plenty of memory while still ensuring that some amount of background work is always possible. All of that is what helps provide a relatively consistent user experience even as the type and volume of device activity changes over time, devices, and users.

With all that context, let me jump back to what I said here:

"....every extension point defines it's own memory limit and that memory limit overrides the value that the "Increased Memory Limit" entitlement modifies."

The reason extension points each define their own limit is because the focus of the extension point system is on allowing lots of small components to run simultaneously. The more memory an app extensions uses, the more often we'll inevitably be forced to either:

  • Terminate the app extension (because other, critical, work must occur).

  • Terminate other work (because the app extension is "more" important).

...expanding exactly the problems we're trying to address.

must we explicitly apply for it?

No. At a purely technical level, I don't think it's actually possible for the system to grant your app extension more memory. The hard limit was applied when launchd created your process and that limit came from a hard coded list of app extension types. I'm not aware of any mechanism that would bypass that.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Increased Memory Limit for QL Preview Generator
 
 
Q