IOS performance debugging and ios performance debugging

Source: Internet
Author: User
Tags call back

IOS performance debugging and ios performance debugging
Performance Tuning Methods:

1. dedicated performance tuning tools

2. code optimization

1. Performance tuning tools:

The following is an introduction to the Performance Tuning tool for iOS:

1.1 static analysis tool-Analyze

I believe that iOS developers will generate many compilation warnings during App Build or Archive. These warnings are generated during compilation, and the static analysis process is similar.XCode ProductUnder the menu, clickAnalyzePerform static analysis on the App.

Analyze mainly analyzes the following four problems:

1. logical error: Access to null pointers or uninitialized variables;

2. Memory Management error: for example, memory leakage;

3. Declaration error: variables that have never been used;

4. API call error: library and framework not included.

1.2 Memory Leak analysis tool-Leaks

ClickProductMenuProfileStartInstrumentsUse Leaks to start dynamic analysis.
When Leaks is selected, the Leaks tool and IOS simulator are automatically started. After Leaks is started, recording starts. With the operation on the App running the simulator, you can view the memory usage in Leaks.

Note: If the project uses ARC, as the operation continues to enable or disable the view, the memory may continue to rise, but this does not necessarily mean that there is a memory leak, the timing of ARC release is not fixed.

There are two columns at the top of Leaks: Allocations and Leaks. The curve on the right shows the memory allocation and Memory leakage curves.

Click Leaks in the second column for Memory Leak analysis. The Leaks debugging option appears in the lower left corner:

We recommend that you set the Interval of Snapshot Interval to 10 seconds. If you select Automatic Snapshotting, Leaks automatically performs memory capture analysis.

You can click Snapshot Now for manual capture before and after you suspect there is a memory leak. <Strong "/kf/ware/vc/" target = "_ blank" class = "keylink"> strong + ILqvyv21xMrTzbyjrL/J0tS3os/strong "write the image description here" src = "/uploadfile/Collfiles/20160429/20160429090352437 .png" title =" \ "/>

The Leaked Object table shows the memory leakage type, quantity, and memory space.

Click a specific memory leakage object, and a possible location will appear in the Detail window on the right. The black Avatar represents the most likely location.

Leaks has successfully found the [CMTool getSubImage:] function:

 Dynamic Analysis of Memory leakage

If you are familiar with Leaks, you will be able to determine more accurately the memory leakage. You can use Snapshot Now to manually capture the leakage.

If the device performs well at the beginning, you can set the automatic capture interval to 5 seconds.

When using ARC projects, memory leaks are generally caused by malloc, custom structures, and resources. Pay more attention to these issues for analysis.

Causes of Memory leakage after ARC is enabled

If ARC is enabled, there will not be any memory problems. Apple's famous saying is: ARC is only for NSObject.

In IOS, the memory allocated by malloc is not processed by ARC and must be processed by itself.

CGImageRef in this example is also an Image pointer, and ARC will not process it.

1.3 unreasonable memory analysis tool-Allocation

In addition to memory leakage, memory usage may be unreasonable, which may cause IOS memory warnings.

Unreasonable use of memory is often more difficult to find than memory leakage. Memory leakage can be judged by more tools. The unreasonable use of memory requires developers to analyze the memory based on code and architecture.

Clearly describe the differences between the two:

Memory leakage: memory is allocated, but there is no pointer to the memory in the program. As a result, the memory cannot be released, and it is always in use, resulting in Memory leakage.

Unreasonable memory usage: Apple officially claims this situation as abandoned memory, which is a reference to allocated memory, but it is not actually used in the program and cached for objects such as slices, but the objects in the cache have never been used.

Provided by XCodeInstrumentsInAllocationThe tool can help you understand the memory Allocation. When your App receives a memory warning, you should first use Allocation for memory analysis to understand which objects occupy too much memory.

1.4 kill botnets-Zombies

The zombie object, that is, the EXC_BAD_ACCESS error we will encounter, is caused by the memory has been released, and this object still keeps this bad address.
In MRC development, this error is common. The code used in C ++ in ARC will also be encountered.
However, this tool is relatively simple. If you encounter such errors, openInstrumentsThe tool below can help you locate it directly. I will not go into details here.

1.5 Performance Improvement Tool-Time Profile

The top priority of this article!

Since it is performance tuning, how to improve the code running efficiency is actually the most direct appeal of our programmers, and this tool can help us do this.

Time Profiler analysis principle:It tracks the stack information of each thread at a fixed interval, calculates how long a method has been executed by comparing the stack status between intervals, and obtains an approximate value. It counts the time spent by each method, forming a good helper for us to directly locate the code that needs optimization.

Select the Time Profiler tool to start the test. The simulator and Time Profiler recording are automatically started.

First, perform some App operations to allow Time Profiler to collect enough data, especially those that have performance bottlenecks.

The panel marked as 4, 5, and 6 should be noted:

4 is the extended panel used to trace and display stacks;

5 is the detailed Panel, where you can see the cpu running time consumption;

6 is the option panel, which can be used to set the runtime parameters of Time Profiler.

You can view the most time-consuming operations on the application in the Detail Panel and view them row by row:

The black icon is the prompt given by Time Profiler. If there may be performance bottlenecks, You can gradually expand down to find the root cause.

Time Profiler parameter settings

The meanings of these options are as follows:

  Separate by Thread: Each Thread should be considered separately. Only in this way can you find the "heavy" threads that occupy a lot of CPU

Invert Call Tree: trace the stack from the top down, which means that the method in the table you see is0Frame sampling starts. This is what you usually want. Only in this way can you see the method with the deepest CPU call fees. that is to say, after selecting this option in FuncA {FunB {FunC}, the stack displays the deepest C in the call Level in the outermost form with a C-> B-A.

Hide Missing Symbols: If dSYM cannot find your app or system framework, you cannot see the method name in the table but only hexadecimal values. If this line is checked, these Symbols can be hidden to simplify data

Hide System Libraries

Show Obj-C Only: Only Show oc code. If your program is a program like OpenGl, do not select the lateral check because it may be C ++

Flatten Recursion: recursive function. Each stack traces an entry.

Top Functions: the sum of the time a function spends in the function and the total time it takes to call the function. Therefore, if function A calls function B, it is very useful to report the time spent by function A plus the time spent by function B, because it allows you to pick the maximum time number each time you go down to the call stack, and return to zero in your most time-consuming method.

The above parameters are reasonably set in practice, and there is not much skill, that is, data hiding and display make us focus more on the data we want to find.

2. code optimization for performance optimization:

The following describes the code optimization that can be performed directly in development.

2.1 set views to opacity (opaque = yes)

(Opaque) This attribute provides the rendering system with a prompt on how to handle this view. If set to YES, the rendering system considers this view to be completely opaque, which enables the rendering system to optimize some rendering processes and improve performance.

If it is set to NO, the rendering system normally forms this View with other content. The default value is YES.

Let me show you a picture. If this attribute is NO, then:

You know, the GPU will use the layer color synthesis formula to synthesize the true color value, which consumes a lot of performance in ScrollView or animation.

2.2 do not block the main thread

Never take too much of the main thread. Because UIKit does all the work on the main thread, rendering, management touch response, and response input all need to be done on it.

The risk of using the main thread is that if your code blocks the main thread, your app will lose response.

In most cases, your app is performing I/O operations involving reading and writing external resources, such as storage or network operations.

We recommend that you use GCD to perform these operations asynchronously and call back the UI-related operations in the main thread, as shown in the following code:

Dispatch_async. });});
2.3 adjust the image size in the ImageView in advance (same as the rendering of the image and animation)

If you wantUIImageViewYou must ensure that the image size is the same as that of UIImageView.
BecauseScaling images at runtime is resource-consuming., EspeciallyUIImageViewNested inUIScrollView.

If the image is loaded from the remote service, you cannot control the image size. For example, if you want to adjust the image size before downloading, you can use background thread to scale the image once after the download is complete, then use the scaled image in UIImageView.

This analogy is common in rendering of images and animations.

For details, refer to the above GCD operation.

2.4 correctly use container features

Arrays: a set of ordered values. Using index to search is very fast, using value to search is very slow, and inserting/deleting is very slow. Dictionaries: stores key-value pairs. It is faster to search with a key. Sets: unordered values. Search quickly with values and insert/delete quickly.

2.5 use gzip for transmission of large files

A large number of apps depend on remote resources and third-party APIs. You may develop an app that needs to download XML, JSON, HTML, or other formats from the remote end.

The problem is that we target mobile devices, so you can't count on the good network conditions. A user is still on the edge network and may switch to 3 GB in the next minute. No matter what the scenario is, you certainly don't want your users to wait too long.

One way to reduce the document size is to open gzip on the server and your app. This is more effective for text data with a higher compression ratio.

Of course, Apple now supports it automatically. You only need to tell your server's students that when transferring large files, remember to use gzip.

2.6 reuse and lazy loading of views

More views mean more rendering, that is, more CPU and memory consumption. This is especially true for apps nested with many views in UIScrollView.

ReuseIt is imitation.UITableViewAndUICollectionViewOperation: do not create all subviews at a time, but create them only when necessary. When they fulfill their mission, put them into a reusable queue.
When you need to use the View, find out whether the View can be reused in the reusable queue.
Here, I used a similar method in my framework to create an image browser. You can refer to it for a moment. View Reuse

Lazy LoadingIt is not loaded when the program starts. It is loaded only when this object is used.
This can be used not only in attributes, but also in View. However, the implementation is slightly different.
Lazy loading consumes less memory, but the display of the View will be slightly delayed.

2.7 Cache

An excellent principle is that what the cache requires is something that is unlikely to change but needs to be read frequently.

What Can We cache? Some options are remote server response, images, and even calculation results, such as the Row Height of UITableView.

By default, NSURLConnection caches Resources in the memory or storage based on the HTTP Headers it loads. You can even manually create an NSURLRequest to load only the cached value.

The following is an available code segment. You can use it to create an NSURLRequest for a basically unchanged image and cache it:

+ (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url {    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];     request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // this will make sure the request always returns the cached image    request.HTTPShouldHandleCookies = NO;    request.HTTPShouldUsePipelining = YES;    [request addValue:@"image/*" forHTTPHeaderField:@"Accept"];     return request;}

Note that you can obtain a URL request through NSURLConnection, and AFNetworking is the same. In this way, you do not have to change all the networking code to use this tip.

If you need to cache other things that are not HTTP Request, you can use NSCache.

2.8 remember to handle memory warnings

Once the system memory is too low, iOS notifies all running apps. In the official document, it is described as follows:

If your app receives a memory warning, it needs to release as much memory as possible. The best way is to remove strong references for cache, image objects, and other objects that can be recreated.

Fortunately, UIKit provides several methods to collect low-memory Warnings:

In app delegate, use the <code> applicationDidReceiveMemoryWarning: </code> method in the subclass of your custom UIViewController) overwrite <code> didReceiveMemoryWarning </code> to register and receive notifications from uiapplicationdidreceivemorywarningnotification.

Once you receive such notifications, you need to release any unnecessary memory usage.

For example, the default behavior of UIViewController is to remove some invisible views. Some of its subclasses can supplement this method to delete some additional data structures. An app with image cache can remove images that are not displayed on the screen.

In this way, it is necessary to process the memory alarm. If you do not pay attention to it, your app may be killed by the system.

However, you must ensure that the selected object can be recreated to release the memory. Be sure to use the memory in the simulator for testing during development.

2.9 reuse large overhead objects

The large sales here refer to someInitialization is slowSuch as NSDateFormatter and NSCalendar. However, you need to use them, such as parsing data from JSON or XML.

To avoid the bottleneck of using this object, you need to reuse them. You can add attributes to your class or create static variables.

Note that if you select the second method, the object will always exist in the memory when your app is running, similar to singleton.

The following code uses a property to delay loading a date formatter. During the first call, it creates a new instance. In future calls, it returns the created instance:

// in your .h or inside a class extension@property (nonatomic, strong) NSDateFormatter *formatter; // inside the implementation (.m)// When you need, just use self.formatter- (NSDateFormatter *)formatter {    if (! _formatter) {        _formatter = [[NSDateFormatter alloc] init];        _formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // twitter date format    }    return _formatter;}

Note that setting an NSDateFormatter is almost as slow as creating a new one! Therefore, if your app needs to process the date format frequently, you will get a significant performance improvement from this method.

2.10 avoid repeated Data Processing

Many applications need to load data in JSON or XML format from the server. It is important to use the same data structure on the server and client. It is costly to operate data in the memory so that they meet your data structure.

For example, if you need data to display a table view, you 'd better retrieve the data in the array structure from the server directly to avoid extra changes in the intermediate data structure.

Similarly, if you want to retrieve data from a specific key, you can use the dictionary of the key-value pair.

2.11 set the background image correctly

Putting background images in a View is like many other iOS programming methods:

Use colorWithPatternImage of UIColor to set the background color. Add a UIImageView to the view as a sub-View.

If you use a full-frame background image, you must use UIImageView because the colorWithPatternImage of UIColor is used to create a small duplicate image as the background. In this case, using UIImageView can save a lot of memory:

// You could also achieve the same result in Interface BuilderUIImageView *backgroundView = [ [UIImageView alloc] initWithImage:[UIImage imageNamed:@"background"]];[self.view addSubview:backgroundView];

If you use a small image tile to create a background, you need to use the colorWithPatternImage of UIColor to make rendering faster and it will not spend much memory:

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background"]];
2.12 try Apple's latest WKWebView to process web

UIWebView is very useful. It is very easy to use to display webpage content or create animations that are hard to achieve by using UIKit.

However, you may notice that the UIWebView is not as fast as the Safari driver. This is due to the limitations of the Nitro Engine of Webkit featuring JIT compilation.

To achieve higher performance, you need to adjust your HTML. The first thing to do is remove unnecessary javascript as much as possible to avoid using too large frameworks. It is better to use only native js.

In addition, load javascript that does not affect page expression, such as user behavior statistics script, asynchronously as much as possible.

Finally, always pay attention to the image you are using to ensure that the image size meets your needs. Use Sprite sheet to increase loading speed and save memory.

Of course, the above is for your use of UIWebView, You need to minimize the use of web features, however, WKWebView, the underlying framework of Safari recently launched by Apple, may help us avoid many such performance problems.

2.13 optimize your TableView

Table view must have good rolling performance. Otherwise, you will find animation flaws During the rolling process.

To ensure smooth table view scrolling, you have taken the following measures:

Correct use of reuseIdentifier to reuse cells try to make all view opaque, including cell itself to avoid gradient, image scaling, background selection and cache line height if the actual content in the cell comes from the web, use asynchronous loading, cache request Results Use shadowPath to draw shadows reduce the number of subviews as much as possible not applicable to cellForRowAtIndexPath: If you need to use it, use only one time and then cache the results using the correct data structure to store data using rowHeight, sectionFooterHeight and sectionHeaderHeight are used to set a fixed height. Do not request delegate.

2.14 select the correct data storage method

What do you do when you store large volumes of data?

You have many options, such:

  Use NSUerDefaults to use XML, JSON, or plist to use NSCoding to Archive Local SQL statements similar to SQLiteThe database uses Core Data

What is the problem with NSUserDefaults? Although it is nice and convenient, it only applies to small data, such as some simple boolean setting options. If it is bigger, you need to consider other methods.

What about structured files like XML? In general, you need to read the entire file to the memory for parsing, which is very economic. Using SAX is a very troublesome task.

NSCoding? Unfortunately, it also needs to read and write files, so there are also the above problems.

In this application scenario, it is better to use SQLite or Core Data. With these technologies, you can use specific query statements to load only the objects you need.

In terms of performance, SQLite and Core Data are very similar. Their difference lies in the specific use method. Core Data represents the graph model of an object, but SQLite is a DBMS. Apple generally recommends using Core Data, but if you have reason not to use it, use a more underlying SQLite.

If you use SQLite, you can use the FMDB (https://github.com/ccgus/fmdb) library to simplify SQLite operations, so you don't have to spend a lot of time learning about the c api of SQLite.

2.15 replace Xib with Storyboard

When you loadXIBAll content is stored in the memory, including any image. If there is a view that will not be used immediately, you are wasting valuable memory resources.

StoryboardsAnother thing is that storyboard only instantiates a view controller when needed.

When XIB is loaded, all images are cached. If you are developing OS X, the same is true for audio files. Apple's description in related documents is:

When you load a nib that references an image or sound resource, the nib Load Code will write the image and sound file into the memory. In OS X, image and sound resources are cached in the named cache for future use. In iOS, only image resources are saved in named caches. Depending on your platform, use NSImage or the 'imagenamed: 'method of UIImage to obtain image resources.

Obviously, the same thing also happens in storyboards, but I have not found any documentation that supports this conclusion.

In addition, it is very important to quickly open the app, especially when the user opens it for the first time. For the app, the first impression is too important.

What you can do is to make it do as many asynchronous tasks as possible, such as loading remote or database data and parsing data.

In other words, avoid too large XIB because they are loaded on the main thread. So try to use Storyboards without this problem!

Note: watchdog does not run when Xcode debug is used. You must disconnect the device from Xcode to test the startup speed.

2.16 learn to manually create Autorelease Pool

NSAutoreleasePoolReleases autoreleased objects in the block. Generally, it is automatically called by UIKit. But in some cases, you also need to manually create it.

If you create many temporary objects, you will find that the memory is decreasing until these objects are release. This is because memory is released only when the UIKit uses autorelease pool.

The good news is that you can create a temporary object in your own @ autoreleasepool to avoid this behavior:

NSArray *urls = [@"url1",@"url2"];for (NSURL *url in urls) {    @autoreleasepool {        NSError *error;        NSString *fileContents = [NSString stringWithContentsOfURL: url encoding: NSUTF8StringEncoding error: &error];        /* Process the string, creating and autoreleasing more objects. */    }}

This code releases all autorelease objects after each traversal.

Reprinted to: Link

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.