Description
The SDK reports memory warning breadcrumbs by subscribing to the addObserverForName:UIApplicationDidReceiveMemoryWarningNotification
|
[NSNotificationCenter.defaultCenter |
|
addObserverForName:UIApplicationDidReceiveMemoryWarningNotification |
|
object:nil |
|
queue:nil |
|
usingBlock:^(NSNotification *notification) { |
|
if (nil != [SentrySDK.currentHub getClient]) { |
|
SentryBreadcrumb *crumb = |
|
[[SentryBreadcrumb alloc] initWithLevel:kSentryLevelWarning |
|
category:@"device.event"]; |
|
crumb.type = @"system"; |
|
crumb.data = @ { @"action" : @"LOW_MEMORY" }; |
|
crumb.message = @"Low memory"; |
|
[SentrySDK addBreadcrumb:crumb]; |
|
} |
|
}]; |
With #2493 we now use a dispatch queue for a more fine grained approach
|
const auto queueAttributes |
|
= dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0); |
|
_memoryWarningQueue = dispatch_queue_create("io.sentry.queue.memory-warnings", queueAttributes); |
|
_memoryWarningSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, |
|
DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN |
|
| DISPATCH_MEMORYPRESSURE_CRITICAL, |
|
_memoryWarningQueue); |
|
__weak auto weakSelf = self; |
|
dispatch_source_set_event_handler(_memoryWarningSource, ^{ |
|
const auto strongSelf = weakSelf; |
|
if (!strongSelf) { |
|
return; |
|
} |
|
handler(dispatch_source_get_data(strongSelf->_memoryWarningSource)); |
|
}); |
|
dispatch_resume(_memoryWarningSource); |
With that we could also create breadcrumbs for DISPATCH_MEMORYPRESSURE_NORMAL
, DISPATCH_MEMORYPRESSURE_WARN
, DISPATCH_MEMORYPRESSURE_CRITICA
. Furthermore, we could add the currently available memory with
|
- (mach_vm_size_t)memoryFootprintBytes:(NSError *__autoreleasing _Nullable *)error |
|
{ |
|
task_vm_info_data_t info; |
|
mach_msg_type_number_t count = TASK_VM_INFO_COUNT; |
|
|
|
const auto status = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&info, &count); |
|
if (status != KERN_SUCCESS) { |
|
if (error) { |
|
*error = NSErrorFromSentryErrorWithKernelError( |
|
kSentryErrorKernel, @"task_info reported an error.", status); |
|
} |
|
return 0; |
|
} |
|
|
|
mach_vm_size_t footprintBytes; |
|
if (count >= TASK_VM_INFO_REV1_COUNT) { |
|
footprintBytes = info.phys_footprint; |
|
} else { |
|
footprintBytes = info.resident_size; |
|
} |
|
|
|
return footprintBytes; |
|
} |
Thermal State
|
- (void)registerStateChangeNotifications |
|
{ |
|
// According to Apple docs: "To receive NSProcessInfoThermalStateDidChangeNotification, you must |
|
// access the thermalState prior to registering for the notification." (from |
|
// https://developer.apple.com/documentation/foundation/nsprocessinfothermalstatedidchangenotification/) |
|
[self recordThermalState]; |
|
|
|
[_processInfoWrapper monitorForThermalStateChanges:self callback:@selector(recordThermalState)]; |
|
|
|
if (@available(macOS 12.0, *)) { |
|
[_processInfoWrapper monitorForPowerStateChanges:self |
|
callback:@selector(recordPowerLevelState)]; |
|
} |
|
} |