Post

Replies

Boosts

Views

Created

[SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
0
0
22
3d
[SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
0
0
13
3d
Subject: [SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Subject: [SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
0
0
10
3d
The options and position arguments do not work in the 'entriesEnumeratorWithOptions:position:predicate:error:' method of the OSLogStore object.
When I set the option parameter to OSLogEnumeratorReverse, the iteration order of OSLogEnumerator is still from front to back in time When I set the options parameter to 0 and the position parameter to the first 5 seconds of the current time, OSLogEnumerator can still iterate over the previous 5 seconds #import "ViewController.h" #import <OSLog/OSLog.h> @interface ViewController () @property(strong, nonatomic)OSLogStore *logStore; @property(strong, nonatomic)NSDateFormatter *formatter; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSError *err = nil; self.logStore = [OSLogStore storeWithScope:OSLogStoreCurrentProcessIdentifier error:&err]; if (!self.logStore || err) { NSLog(@"error: %@", err); NSAssert(0, @""); } self.formatter = [[NSDateFormatter alloc] init]; [self.formatter setDateFormat:@"[yyyy-MM-dd HH:mm:ss:SSS]"]; } - (IBAction)addLog:(id)sender { static int i = 0; NSLog(@"[test] %@ this is a log with index:%d", [self.formatter stringFromDate:[NSDate date]], i++); } - (IBAction)printLogWithReverse:(id)sender { NSError *err = nil; NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]]; OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:OSLogEnumeratorReverse position:nil predicate:preeicate error:&err]; if (err) { NSLog(@"enumer error:%@", err); NSAssert(0, @""); } OSLogEntryLog *entry = nil; while (entry = [enumer nextObject]) { NSString *message = [entry composedMessage]; printf("log: %s\n", message.UTF8String); } } - (IBAction)printLogWithPosition:(id)sender { NSError *err = nil; NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]]; NSDate *posDate = [NSDate dateWithTimeIntervalSinceNow:-5]; OSLogPosition *pos = [self.logStore positionWithDate:posDate]; OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:0 position:pos predicate:preeicate error:&err]; if (err) { NSLog(@"enumer error:%@", err); NSAssert(0, @""); } const char *now = [self.formatter stringFromDate:[NSDate date]].UTF8String; const char *posStart = [self.formatter stringFromDate:posDate].UTF8String; OSLogEntryLog *entry = nil; while (entry = [enumer nextObject]) { NSString *message = [entry composedMessage]; printf("log(now:%s, pos:%s): %s\n", now, posStart, message.UTF8String); } } @end The method of - (IBAction)printLogWithReverse:(id)sender print result not reversed by time. log: [test] [2025-02-18 17:35:50:175] this is a log with index:0 log: [test] [2025-02-18 17:35:51:040] this is a log with index:1 log: [test] [2025-02-18 17:35:51:174] this is a log with index:2 log: [test] [2025-02-18 17:35:51:323] this is a log with index:3 log: [test] [2025-02-18 17:35:51:473] this is a log with index:4 log: [test] [2025-02-18 17:35:51:640] this is a log with index:5 log: [test] [2025-02-18 17:35:51:773] this is a log with index:6 log: [test] [2025-02-18 17:35:51:923] this is a log with index:7 The method of - (IBAction)printLogWithPosition:(id) print result should not contain the log from 5 seconds ago because I set the start time position in the position argument [test] [2025-02-18 17:43:58:741] this is a log with index:0 [test] [2025-02-18 17:43:58:940] this is a log with index:1 [test] [2025-02-18 17:43:59:458] this is a log with index:2 [test] [2025-02-18 17:43:59:923] this is a log with index:3 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:741] this is a log with index:0 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:940] this is a log with index:1 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:458] this is a log with index:2 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:923] this is a log with index:3
1
0
433
Feb ’25
In statistical objects In MXMetricPayload histogrammedTimeToFirstDrawKey start times not equal applicationExitMetrics exit
In statistical objects In MXMetricPayload histogrammedTimeToFirstDrawKey start times not equal applicationExitMetrics exit: case1: "applicationExitMetrics": { "backgroundExitData": { "cumulativeNormalAppExitCount": 3, "cumulativeMemoryPressureExitCount": 4 }, "foregroundExitData": { "cumulativeMemoryResourceLimitExitCount": 3 } }, "applicationLaunchMetrics": { "histogrammedTimeToFirstDrawKey": { "histogramNumBuckets": 14, "histogramValue": { "10": { "bucketCount": 1, "bucketStart": "1740 ms", "bucketEnd": "1749 ms" }, "2": { "bucketCount": 1, "bucketStart": "1440 ms", "bucketEnd": "1449 ms" }, "3": { "bucketCount": 2, "bucketStart": "1490 ms", "bucketEnd": "1499 ms" }, "11": { "bucketCount": 1, "bucketStart": "1780 ms", "bucketEnd": "1789 ms" }, "4": { "bucketCount": 1, "bucketStart": "1500 ms", "bucketEnd": "1509 ms" }, "5": { "bucketCount": 1, "bucketStart": "1580 ms", "bucketEnd": "1589 ms" }, "12": { "bucketCount": 1, "bucketStart": "1860 ms", "bucketEnd": "1869 ms" }, "6": { "bucketCount": 1, "bucketStart": "1620 ms", "bucketEnd": "1629 ms" }, "13": { "bucketCount": 1, "bucketStart": "1990 ms", "bucketEnd": "1999 ms" }, "7": { "bucketCount": 1, "bucketStart": "1650 ms", "bucketEnd": "1659 ms" }, "0": { "bucketCount": 1, "bucketStart": "1400 ms", "bucketEnd": "1409 ms" }, "8": { "bucketCount": 1, "bucketStart": "1660 ms", "bucketEnd": "1669 ms" }, "1": { "bucketCount": 1, "bucketStart": "1430 ms", "bucketEnd": "1439 ms" }, "9": { "bucketCount": 1, "bucketStart": "1730 ms", "bucketEnd": "1739 ms" } } }, In this Case the app cold started 15 times, but quit only 10 times, why?? case2: "applicationExitMetrics": { "backgroundExitData": { "cumulativeMemoryPressureExitCount": 1 }, "foregroundExitData": { "cumulativeMemoryResourceLimitExitCount": 3, "cumulativeNormalAppExitCount": 1 } }, "applicationLaunchMetrics": { "histogrammedTimeToFirstDrawKey": { "histogramNumBuckets": 3, "histogramValue": { "0": { "bucketCount": 1, "bucketStart": "1490 ms", "bucketEnd": "1499 ms" }, "1": { "bucketCount": 1, "bucketStart": "1680 ms", "bucketEnd": "1689 ms" }, "2": { "bucketCount": 1, "bucketStart": "1880 ms", "bucketEnd": "1889 ms" } } }, The app cold started 3 times, but quit unexpectedly reached 5 times, why???
1
1
789
Apr ’24
[SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
Replies
0
Boosts
0
Views
22
Activity
3d
[SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
Replies
0
Boosts
0
Views
13
Activity
3d
Subject: [SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage
Subject: [SDK / Instruments] Clarification on Runnable & Blocked Time Semantics — Customers Misinterpreting as CPU Usage Hi Apple Developer Technical Support Team, I hope this message finds you well. I am writing to seek urgent clarification on a profiling question that is directly impacting our SDK customers. Context We provide an iOS SDK that is integrated into third-party applications. Our SDK includes a background monitoring thread created via: -[NSObject performSelectorInBackground:withObject:] As documented, threads created through this API carry a default (relatively low) scheduling priority. Inside the thread, we call sleep(1) once per second for periodic idle intervals, and we collect CPU usage metrics using kernel APIs: • task_threads() • thread_info() Both calls involve kernel-level operations and are known to trigger context switches internally. The Core Issue — Customer Misinterpretation When our customers profile their apps using Instruments with "Context Switch Sampling" enabled, they observe that our SDK thread shows a large proportion of time labeled as "Runnable" and "Blocked". A representative example: • Total (wall clock): 4.30 s — 100% • Runnable: 3.06 s — 71.4% ← customers flag this as high CPU usage • Blocked: 1.05 s — 24.5% • Running: 176 ms — 4.1% ⚠️ Our customers are interpreting the "Runnable" time (71.4%) as CPU consumption by our SDK, and are raising concerns that our SDK is degrading their app's performance. We strongly believe this interpretation is incorrect — a thread in the "Runnable" state is merely waiting in the scheduler's ready queue and has NOT been assigned to any CPU core, therefore it should NOT consume any CPU resources. However, we need an official confirmation from Apple to address our customers' concerns definitively. Our Questions Do the time values shown next to "Runnable" and "Blocked" in the Time Profiler call tree represent wall-clock waiting time (i.e., time spent in that state), or actual CPU consumption time? Does a thread in the "Runnable" state consume any CPU resources on the device? We want to confirm clearly: does Runnable time contribute to CPU load or battery drain in any way? Is it correct that the high Runnable time observed is caused by the combination of: a. The low thread scheduling priority assigned by performSelectorInBackground:withObject:, and b. Context switch overhead introduced by the task_threads() and thread_info() kernel calls? Is there any official Apple documentation that explicitly describes the semantics of "Runnable" and "Blocked" time in Instruments, which we could reference when communicating with our customers? An authoritative answer from Apple would allow us to accurately explain the profiling data to our customers and clarify that the high "Runnable" time does NOT represent CPU consumption by our SDK. Thank you very much for your time and support. Best regards
Replies
0
Boosts
0
Views
10
Activity
3d
The options and position arguments do not work in the 'entriesEnumeratorWithOptions:position:predicate:error:' method of the OSLogStore object.
When I set the option parameter to OSLogEnumeratorReverse, the iteration order of OSLogEnumerator is still from front to back in time When I set the options parameter to 0 and the position parameter to the first 5 seconds of the current time, OSLogEnumerator can still iterate over the previous 5 seconds #import "ViewController.h" #import <OSLog/OSLog.h> @interface ViewController () @property(strong, nonatomic)OSLogStore *logStore; @property(strong, nonatomic)NSDateFormatter *formatter; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSError *err = nil; self.logStore = [OSLogStore storeWithScope:OSLogStoreCurrentProcessIdentifier error:&err]; if (!self.logStore || err) { NSLog(@"error: %@", err); NSAssert(0, @""); } self.formatter = [[NSDateFormatter alloc] init]; [self.formatter setDateFormat:@"[yyyy-MM-dd HH:mm:ss:SSS]"]; } - (IBAction)addLog:(id)sender { static int i = 0; NSLog(@"[test] %@ this is a log with index:%d", [self.formatter stringFromDate:[NSDate date]], i++); } - (IBAction)printLogWithReverse:(id)sender { NSError *err = nil; NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]]; OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:OSLogEnumeratorReverse position:nil predicate:preeicate error:&err]; if (err) { NSLog(@"enumer error:%@", err); NSAssert(0, @""); } OSLogEntryLog *entry = nil; while (entry = [enumer nextObject]) { NSString *message = [entry composedMessage]; printf("log: %s\n", message.UTF8String); } } - (IBAction)printLogWithPosition:(id)sender { NSError *err = nil; NSPredicate *preeicate = [NSPredicate predicateWithFormat:@"composedMessage contains %@" argumentArray:@[@"[test]"]]; NSDate *posDate = [NSDate dateWithTimeIntervalSinceNow:-5]; OSLogPosition *pos = [self.logStore positionWithDate:posDate]; OSLogEnumerator *enumer = [self.logStore entriesEnumeratorWithOptions:0 position:pos predicate:preeicate error:&err]; if (err) { NSLog(@"enumer error:%@", err); NSAssert(0, @""); } const char *now = [self.formatter stringFromDate:[NSDate date]].UTF8String; const char *posStart = [self.formatter stringFromDate:posDate].UTF8String; OSLogEntryLog *entry = nil; while (entry = [enumer nextObject]) { NSString *message = [entry composedMessage]; printf("log(now:%s, pos:%s): %s\n", now, posStart, message.UTF8String); } } @end The method of - (IBAction)printLogWithReverse:(id)sender print result not reversed by time. log: [test] [2025-02-18 17:35:50:175] this is a log with index:0 log: [test] [2025-02-18 17:35:51:040] this is a log with index:1 log: [test] [2025-02-18 17:35:51:174] this is a log with index:2 log: [test] [2025-02-18 17:35:51:323] this is a log with index:3 log: [test] [2025-02-18 17:35:51:473] this is a log with index:4 log: [test] [2025-02-18 17:35:51:640] this is a log with index:5 log: [test] [2025-02-18 17:35:51:773] this is a log with index:6 log: [test] [2025-02-18 17:35:51:923] this is a log with index:7 The method of - (IBAction)printLogWithPosition:(id) print result should not contain the log from 5 seconds ago because I set the start time position in the position argument [test] [2025-02-18 17:43:58:741] this is a log with index:0 [test] [2025-02-18 17:43:58:940] this is a log with index:1 [test] [2025-02-18 17:43:59:458] this is a log with index:2 [test] [2025-02-18 17:43:59:923] this is a log with index:3 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:741] this is a log with index:0 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:58:940] this is a log with index:1 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:458] this is a log with index:2 log(now:[2025-02-18 17:44:51:132], pos:[2025-02-18 17:44:46:032]): [test] [2025-02-18 17:43:59:923] this is a log with index:3
Replies
1
Boosts
0
Views
433
Activity
Feb ’25
In statistical objects In MXMetricPayload histogrammedTimeToFirstDrawKey start times not equal applicationExitMetrics exit
In statistical objects In MXMetricPayload histogrammedTimeToFirstDrawKey start times not equal applicationExitMetrics exit: case1: "applicationExitMetrics": { "backgroundExitData": { "cumulativeNormalAppExitCount": 3, "cumulativeMemoryPressureExitCount": 4 }, "foregroundExitData": { "cumulativeMemoryResourceLimitExitCount": 3 } }, "applicationLaunchMetrics": { "histogrammedTimeToFirstDrawKey": { "histogramNumBuckets": 14, "histogramValue": { "10": { "bucketCount": 1, "bucketStart": "1740 ms", "bucketEnd": "1749 ms" }, "2": { "bucketCount": 1, "bucketStart": "1440 ms", "bucketEnd": "1449 ms" }, "3": { "bucketCount": 2, "bucketStart": "1490 ms", "bucketEnd": "1499 ms" }, "11": { "bucketCount": 1, "bucketStart": "1780 ms", "bucketEnd": "1789 ms" }, "4": { "bucketCount": 1, "bucketStart": "1500 ms", "bucketEnd": "1509 ms" }, "5": { "bucketCount": 1, "bucketStart": "1580 ms", "bucketEnd": "1589 ms" }, "12": { "bucketCount": 1, "bucketStart": "1860 ms", "bucketEnd": "1869 ms" }, "6": { "bucketCount": 1, "bucketStart": "1620 ms", "bucketEnd": "1629 ms" }, "13": { "bucketCount": 1, "bucketStart": "1990 ms", "bucketEnd": "1999 ms" }, "7": { "bucketCount": 1, "bucketStart": "1650 ms", "bucketEnd": "1659 ms" }, "0": { "bucketCount": 1, "bucketStart": "1400 ms", "bucketEnd": "1409 ms" }, "8": { "bucketCount": 1, "bucketStart": "1660 ms", "bucketEnd": "1669 ms" }, "1": { "bucketCount": 1, "bucketStart": "1430 ms", "bucketEnd": "1439 ms" }, "9": { "bucketCount": 1, "bucketStart": "1730 ms", "bucketEnd": "1739 ms" } } }, In this Case the app cold started 15 times, but quit only 10 times, why?? case2: "applicationExitMetrics": { "backgroundExitData": { "cumulativeMemoryPressureExitCount": 1 }, "foregroundExitData": { "cumulativeMemoryResourceLimitExitCount": 3, "cumulativeNormalAppExitCount": 1 } }, "applicationLaunchMetrics": { "histogrammedTimeToFirstDrawKey": { "histogramNumBuckets": 3, "histogramValue": { "0": { "bucketCount": 1, "bucketStart": "1490 ms", "bucketEnd": "1499 ms" }, "1": { "bucketCount": 1, "bucketStart": "1680 ms", "bucketEnd": "1689 ms" }, "2": { "bucketCount": 1, "bucketStart": "1880 ms", "bucketEnd": "1889 ms" } } }, The app cold started 3 times, but quit unexpectedly reached 5 times, why???
Replies
1
Boosts
1
Views
789
Activity
Apr ’24