0

I am receiving memory warnings in didReceiveMemoryWarning. I know memory warnings have different levels like level-1,level-2. Is there any way determine the warning level? Example:

if(warning level == 1)
    <blah>
Olie
  • 24,597
  • 18
  • 99
  • 131
Ankit Vyas
  • 7,507
  • 13
  • 56
  • 89

4 Answers4

2

Hope this helps!!!

There are 4 levels of warnings (0 to 3). These are set from the kernel memory watcher, and can be obtained by the not-so-public function OSMemoryNotificationCurrentLevel().

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

How the levels are triggered is not documented. SpringBoard is configured to do the following in each memory level:

Warning (not-normal) — Relaunch, or delay auto relaunch of nonessential background apps e.g. Mail.
Urgent — Quit all background apps, e.g. Safari and iPod.
Critical and beyond — The kernel will take over, probably killing SpringBoard or even reboot.
sparta
  • 56
  • 2
1

I know there is no way to (except the private/undocumented API) know the memory level warning. So you should not use that.

Check out this question to see undocumented API to get memory warning level.

Community
  • 1
  • 1
msk
  • 8,885
  • 6
  • 41
  • 72
0

My first advice would be to research the memory warning notification in the docs (e.g., what are the contents of its userInfo dictionary, if present). I don't know if it provides any details or not.

But ultimately, you shouldn't speculate on the level of the memory warning, just assume the worst and release as much unused data as you can.

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
0

There is no (public, working) way to get the current memory pressure level from the system on a customer device. There is however a way to get notified of memory pressure changes using the Dispatch Source API.

Memory pressure dispatch sources can be used to notify an application of changes to memory pressure. This can be more fine-grained than the notifications provided by UIKit and includes the capability to be notified when memory pressure returns to normal.

For example:

Objective-C:

dispatch_source_t   memorySource    = NULL;

memorySource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0L, (DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL), [self privateQueue]);
if (memorySource != NULL) {
    dispatch_block_t eventHandler = dispatch_block_create(DISPATCH_BLOCK_ASSIGN_CURRENT, ^{
        if (dispatch_source_testcancel(memorySource) == 0 ){
            dispatch_source_memorypressure_flags_t  memoryPressure    = dispatch_source_get_data(memorySource);

            [self didReceiveMemoryPressure:memoryPressure];
        }
    });

   dispatch_source_set_event_handler(memorySource, eventHandler);
   dispatch_source_set_registration_handler(memorySource, eventHandler);
   [self setSource:memorySource];
   dispatch_activate([self source]);
}

Swift 4:

if let source:DispatchSourceMemoryPressure = DispatchSource.makeMemoryPressureSource(eventMask: .all, queue:self.privateQueue) as? DispatchSource {

    let eventHandler: DispatchSourceProtocol.DispatchSourceHandler = {
        let event:DispatchSource.MemoryPressureEvent = source.data
        if source.isCancelled == false {
            self.didReceive(memoryPressureEvent: event)
        }
    }

    source.setEventHandler(handler:eventHandler)
    source.setRegistrationHandler(handler:eventHandler)
    self.source = source
    self.source?.activate()
}

Note that the event handler is also being used as the "registration handler". This will cause the event handler to fire when the dispatch source is activated, effectively telling the application of what the "current" value is when the source is activated.

quellish
  • 21,123
  • 4
  • 76
  • 83
  • This code is incomplete. See https://gist.github.com/steipete/33af275cc1cb419b0f01 for a working example. – bk138 May 10 '19 at 15:19