• The SDK is divided intoMonitorPerformance monitoring data acquisition and Exception Exception error acquisition of two parts. The specific implementation of the test opportunity will first carry out a wave of optimization in the offline prosecution stage based on the theoretical value experience and the detection of development tools. Set a goodExceptionTheoretical error threshold.
  • MonitorPerformance monitoring acquisition will collect the user page performance data and save it as a local file, report and record the monitoring file when opening the APP, parse the file, and statistic the frame rate/memory /CPU threshold alarm data by model and system.
  • ExceptionException error fetching includes:SignalExceptionCrash exception,UncaughtExceptionCrash exception,FpsExceptionFrame rate stalling is abnormal.cpuExceptionUsage limit exceeded,viewDurationExceptionThe page view displays too much time,networkExceptionThe network interface data is abnormal.
  • willMonitorPerformance monitoring collection and analysis indicators as performance reference points for special optimization. In the later stage, a large amount of indicator data collected can also be used to make use of machine learning knowledge through iOSCordeMLThe framework loads the model output of machine learning trainingExceptionA reasonable threshold is required.

1. Caton –SDK online performance monitoring

1.1 Page frame rate monitoring

  • In iOS, the smooth screen refresh rate is 60Hz (60 times per second). Multiple frame drops or large deviations from the refresh value of 16.7ms can be considered as stalling. Based on theCADisplayLinkImplement THE FPS monitoring indicator.
  • A screen refresh signal is emitted every time the page is refreshed,CADisplayLinkAllows us to register a callback processing synchronized with the refresh signal.
  • CADisplayLinkCalls the specified with the frequency of the screen refreshselectorThat is, called every time the screen refreshesselectorIn theselectorMethod counts the number of times this method is executed per second, and the refresh rate of the current screen can be obtained by the number of times/time.
  • Frequent frame hops or persistently low frame rates indicate a problem with fluency.

1.2 Page stuck monitoring

  • Combine framerate change monitoring data with **4.1 **CPU usage

2. Time consuming –SDK online performance monitoring

2.1 APP startup time monitoring

  • Cold startup: Total cold startup time of App = T1 (loading time before main()) + T2 (loading time after main()).

T1 = load time of dylib (dynamic link library) and App executable of the system;

After t2 = the main () function performs the AppDelegate class applicationDidFinishLaunching method performs before the end of this period of time.

During the t1 stage of development, xcode’s Run → Environment Variables will be collected.

During t2, code injection will be used for calculation development and online continuous monitoring and reporting.

  • Hot start: The life cycle function of the app is monitored.applicationWillEnterForeground(Will enter the front desk) ~applicationDidBecomeActive(has become the front desk) between the calculation time for continuous monitoring and reporting.

2.2 Page start time monitoring

Solution a:

Hook Page opening method operation and injection: The asynchronous thread starts the timer, takes a screenshot every 100ms, analyzes the view and determines whether the screen is blank or preloaded until the screen is not blank or the time threshold is reached, and records the loading time of the interval.

Scheme 2

The observer’s mode generates an NSKVO_Controller class and hooks the current page startup method viewDidLoad to record how long the current page takes to create a control.

2.3 Shows network data loading time monitoring

Solution a:

Hook Network data page startLoading method, injection: asynchronous thread starts the timer, takes a screenshot every 100ms, analyzes the view to determine whether there is a loading graph and whether the page is blank or preloading screen, until there is a text end or time threshold in view analysis, and records the loading time in the range.

Scheme 2:

  • If the page appearstableView,collectionViewControl, you can use the hook proxy method cell to appear the method (tableView:willDisplayCell:forRowAtIndexPath:), do time statistics here.
  • If the interface does not containtableView,collectionViewControl to define a base class method that creates a view in a base class.createUI), through hook this base class method to achieve time statistics. (Large changes for projects)

3. Heat and power consumption –SDK online performance monitoring

3.1 CPU usage monitoring

  • While the process is running, each thread has different CPU usage. The sum of CPU usage of each thread can be regarded as the CPU usage of the current App.
  • Based on the Mach kernel bottom class, the underlying principle of obtaining the app startup runtime is actually operated on the Mach kernel bottom class. In Mach it is revealed that it exists in every threadthread_basic_infoStructure, which stores CPU usage. Obtained by operating on the underlying codeMach task, and then you can get thread informationthread_basic_infoStructure.
  • So total CPU usage in real time, more than 60 percent? When the volume is abnormal, thread data and pages with high CPU usage are extracted.

3.2 Network traffic monitoring

  • NSURLProtocol: Uses inherited abstract classesNSURLProtocolIntercepting incoming network requests,initWithRequestdidReceiveResponse.didReceiveDataMethod to record key attributes as the basis for obtaining downstream traffic data.NSURLProtocolWay to write a certain amount of code to achieve, andNSURLProtocolYou can’t block all types of requestsNSURLSessionLaunched by theshareSessionThe form is treated separately.
  • NetworkExtension: in the future business development and model ratio, if our app can allow users to abandon iOS9 below, then we can take over all network requests in the official NetworkExtension library to obtain data.

4. Memory — offline performance check

4.1 Memory leak detection

  • Memory leaks are at the level of fixed code writing.

4.2 Memory Overflow Monitoring

  • During development, development tools are used to observe memory changes generated by recording pages
  • The code scheme attempts the Hook memory allocation method, which records and captures the stack and memory size of memory allocation per page.
  • Analyze the objects of the resulting page, and then implement manually where there may be and where the loop accumulates a large number of objectsautoReleasePoolAutomatic release pool.

4.3 I/O Detection

  • Our app doesn’t use many scenarios for reading and writing locally stored files, so the performance issues here should be minimal.
  • useInstrumentstoolSystem Usage,The File Activity and Network. Collect the file and network IO operation data of applications in the running state.

5. Project slimming — offline performance control

  • Use FUI (Find Unused Imports) to periodically scan for Unused classes in a project
  • APPCode periodically checks for unwanted code in the project
  • Manage compressed file resources

6. Store the obtained data

6.1 Monitor Monitors statistics storage

  • The monitored data is stored in a JSON file named model + system version + APP name + APP version. The life cycle of each app counts as a statistics file and is saved to the sandbox. The format of gzip compression upload, each startup APP, background threads upload to the background service, each time a maximum of 10 files. If the upload fails, the file is saved to the local host for the next upload.
  • File content contains frame rates for each pageFps.CpuThe usage page displays the data at the time of monitoring the data. The page name is the key and the value is the array, which contains:
    • keepTimePage stay duration,openTimesPage open times.
    • For this pagefps_maxThe maximum value,fps_minThe minimum value,fps_avgsQuality value (string concatenation, first 30s,fpsChange per second),fps_totaLife cycle pagesfpsAnd.
    • cpu_maxMaximum usage,cpu_minMinimum usage,cpu_avgsUsage quality value (string concatenation, first 30s,cpuChange per second),cpu_totalLife cycle pagescpuAnd.
    • viewDuration_maxThe maximum startup time is displayed.viewDuration_minThe page displays the minimum startup time,viewDuration_avgsQuality value of page startup time (string concatenation, time per page open)
  • The file content contains the monitoring of APP information, including internaldev_idDevice ID,dev_nEquipment model,system_vEquipment system,app_nappThe name,app_vappVersion,network_typeNetwork type,timeStartup timestamp,app_launchDurationCold startup time, hot startup time (string concatenation).

3.5.2_1585536369.json The statistics file contains the following content:

{
  "APP" : {
    "dev_id" : "03715FB2-0C31-4C65-9AE7-92A4A5E8DCEF"."system_v" : "12.3.1"."app_launchDuration" : "4.804108"."dev_n" : "IPhone9, 2"."time" : "1585536369"."app_n" : "XXX"."app_hotLoadDuration" : "0.297370, 0.297456,"."app_v" : "3.5.2"."network_type" : "WIFI"
  },
  "page" : {
    "ECProductDetailController" : {
      "cpu_min" : "3"."viewDuration_max" : "0.733516"."keepTime" : "30"."fps_min" : "40"."viewDuration_total" : "1.297453"."cpu_total" : "600"."cpu_avgs" : "86,46,33,25,10,9,11,11,7,6,37,10,41,22,12,15,13,11,8,7,6,23,6,8,3,17,66,30,9,12"."fps_avgs" : "43,58,60,60,60,60,59,60,60,60,50,60,50,60,60,60,60,60,60,40,60,58,60,55,45,59,60,60,60,58"."viewDuration_min" : "0.251687"."cpu_max" : "86"."fps_max" : "60"."viewDuration_avgs" : "0.733516, 0.251687, 0.312250,"."fps_total" : "1715"."openTimes" : "3"
    },
    "ECHomePageController" : {
      "cpu_min" : "2"."viewDuration_max" : "2.586971"."keepTime" : "14"."fps_min" : "46"."viewDuration_total" : "2.586971"."cpu_total" : "321"."cpu_avgs" : "9,2,50,34,11,28,34,44,15,28,16,13,16,21"."fps_avgs" : "59,60,48,58,60,60,46,55,60,58,59,57,60,59"."viewDuration_min" : "2.586971"."cpu_max" : "50"."fps_max" : "60"."viewDuration_avgs" : "2.586971"."fps_total" : "799"."openTimes" : "1"
    },
    "FLBFlutterViewContainer" : {
      "cpu_min" : "5"."cpu_avgs" : "56,69,43,5,5,10"."fps_avgs" : "41,35,60,60,60,60"."keepTime" : "6"."fps_min" : "35"."cpu_max" : "69"."fps_total" : "316"."cpu_total" : "188"."fps_max" : "60"}}}Copy the code

6.2 Exception Exception Error Storage

It is saved as a TXT file, which contains dev_id device ID, dev_n device model, system_v device system, app_n name, app_V version, network_type network type, time startup timestamp, name page name, Reason Specifies the error value (FPS, CPU). Exception ErrorType ErrorType, stack information, etc. Can access nail nail Webhook alarm and upload their own background system according to business.

  • SignalExceptionCollapse of abnormal
  • UncaughtExceptionCollapse of abnormal
  • FpsExceptionFrame rate stalling is abnormal (the frame rate lasts for about 3 seconds and is less than the set threshold of 40. Save error records and send error alarms)
  • cpuExceptionUsage exceeds the threshold (frame rate lasts about 3 seconds and exceeds the set threshold 60, save error records and send error alarms)
  • viewDurationExceptionPage view displays too much time
  • networkExceptionNetwork interface data is abnormal (HTTP response code is not 200 or failed)

For example, 3.5.2_1585537822. Json The following is an exception error report:

< b > send exception error report < / b > < b > app_n: < / b > < b > XXX app_v: < / b > 3.5.2 < b > system_v: < / b > 12.3.1 < b > dev_n: < / b > iPhone9, 2 < b > dev_id: </b> 03715FB2-0c31-4c65-9AE7-92a4a5e8dcef <b> Network_type: </b>WIFI <b>time: </b>1585537822 <b>ErrorType: </b>SignalException <b>callStackSymbols:</b> 0 enjoyChanging 0x000000010162af08 SignalExceptionHandler + 140 1 enjoyChanging 0x000000010170ff28 BLYBSDSignalHandlerCallback + 256 2 libsystem_platform.dylib 0x000000018eba19ec <redacted> + 56 3 libsystem_pthread.dylib 0x000000018eba7094 <redacted> + 380 4 libsystem_c.dylib 0x000000018ea87ea8 abort + 140 5 libc++abi.dylib 0x000000018e154788 __cxa_bad_cast + 0 6 libc++abi.dylib 0x000000018e154934 <redacted> + 0 7 libobjc.A.dylib 0x000000018e16be00 <redacted> + 124 8 enjoyChanging 0x0000000101733358 _ZL24BLYCPPExceptionTerminatev + 1932 9 libc++abi.dylib 0x000000018e160838 <redacted> + 16 10 libc++abi.dylib 0x000000018e160434 __cxa_rethrow + 144 11  libobjc.A.dylib 0x000000018e16bbc8 objc_exception_rethrow + 44 12 CoreFoundation 0x000000018ef1d11c CFRunLoopRunSpecific + 544 13 GraphicsServices 0x000000019111d79c GSEventRunModal + 104 14 UIKitCore 0x00000001bb8cb978 UIApplicationMain + 212 15 enjoyChanging 0x0000000100e4a7e0 main + 160 16 libdyld.dylib 0x000000018e9e28e0 <redacted> + 4Copy the code