Performance Optimization-Memory leakage solution

Source: Internet
Author: User

Solution to memory leakage

Memory leakage (memory leaks) means that when an object or variable is not released after use, the object occupies the memory until the application stops. If this type of object is too large, the memory will be exhausted, and other applications will not be able to run. This problem is common in MRR of C ++, C, and objective-C.

In objective-C, the memory for releasing objects is to send the release and autorelease messages, both of which can reduce the reference count by 1. When the reference count is 0, the release message will immediately release the object, the autorelease message puts the object into the memory release pool for delayed release.

Code:

-(Void) viewdidload {[Super viewdidload]; nsbundle * bundle = [nsbundle mainbundle]; nsstring * plistpath = [bundle pathforresource: @ "team" oftype: @ "plist"]; // obtain all data in the property list file self. listteams = [[nsarray alloc] initwithcontentsoffile: plistpath];}-(uitableviewcell *) tableview :( uitableview *) tableview cellforrowatindexpath :( nsindexpath *) indexpath {static nsstring * cellidentifier = @ "cellidentifier"; uitablevie Wcell * cell = [tableview failed: cellidentifier]; If (cell = nil) {Cell = [[uitableviewcell alloc] initwithstyle: uitableviewcellstyledefault reuseidentifier: cellidentifier];} nsuinteger ROW = [indexpath row]; nsdictionary * rowdict = [self. listteams objectatindex: Row]; cell. textlabel. TEXT = [rowdict objectforkey: @ "name"]; nsstring * ImagePath = [rowdict objectforkey: @ "image"]; I Magepath = [ImagePath stringbyappendingstring :@". PNG "]; cell. imageview. image = [uiimage imagenamed: ImagePath]; cell. accessorytype = custom; return cell;}-(void) tableview :( uitableview *) tableview didselectrowatindexpath :( nsindexpath *) indexpath {nsuinteger ROW = [indexpath row]; nsdictionary * rowdict = [self. listteams objectatindex: Row]; nsstring * rowvalue = [rowdict Objectforkey: @ "name"]; nsstring * message = [[nsstring alloc] initwithformat: @ "you have selected the % @ Team .", Rowvalue]; uialertview * Alert = [[uialertview alloc] initwithtitle: @ "select team" message: messagedelegate: selfcancelbuttontitle: @ "OK" Comment: Nil]; [alert show]; [tableview deselectrowatindexpath: indexpath animated: Yes];}

 

Let's take a look at the problems with the above three methods? If the code is based on arc, there is no problem. Unfortunately, based on MRR, the above Code has the possibility of Memory leakage. Theoretically, the internal storage leakage is caused by the absence of objects or variables, but it has been proved that not all unreleased objects or variables may cause memory leakage, which is related to the hardware environment and the operating system environment, therefore, we need detection tools to help us find these "leak points ".

In xcode, two tools are provided to help you find leakage points: Analyze and profile. Analyze is a static analysis tool that can be started from the menu product> analyze to provide the code screen after static analysis; profile is a dynamic analysis tool called "instruments". It is integrated with xcode and can be started through the menu product> profile in xcode. instruments has many trace templates (tracking templates) allows you to dynamically analyze and track memory, CPU, and file systems.

We can use two tools to find leakage points. First, we can use analyze static analysis to find suspicious leakage points, and then use the leaks and allocations tracking templates in profile Dynamic Analysis for dynamic tracking and analysis, check whether these points are leaked or new leaks occur.

The line segment indicates the path of program execution. In this path, 1 indicates that the reference count of the 25 lines of objective-C object is 1, description: an objective-C object is created here. 2: The reference count in Row 27 is 1. This object is not released and is suspected to have been leaked. This explanation clearly tells us the problem. [[nsarray alloc] initwithcontentsoffile: plistpath] creates an object and assigns it to the member variable represented by the listteams attribute, however, after assigning values, the created object does not display the release and autorelease messages. Code Modification

NSArray *array = [[NSArray alloc] initWithContentsOfFile:plistPath];self.listTeams = array;[array release];

 

 

Let's take a look at tableview: cellforrowatindexpath: the blue icon at the end of the suspected leak point row in the method to show the analysis result.

It mainly indicates that cell objects of the uitableviewcell * type may leak in 64 rows. In the table view, the tableview: cellforrowatindexpath: Method instantiates table View cells and sets data. Therefore, the cell object cannot be immediately release after instantiation. autorelease should be used for delayed release. You can send the autorelease message when creating the cell object. The code is modified as follows:

if (cell == nil) {cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];}

 

 

Let's take a look at tableview: didselectrowatindexpath: There are two suspected leak points in the method, and the icon at the end of the line expands the analysis result.

 

The message object is not released after it is created. You only need to add the [Message release] statement code after [alert show. There are two ways to instantiate an object in objective-C:

Nsstring * message = [[nsstring alloc] initwithformat: @ "you have selected the % @ Team .", Rowvalue]; ①

Nsstring * message = [nsstring stringwithformat: @ "you have selected the % @ Team. ", Rowvalue]; ②

① The line shows the constructor starting with init-. It calls the constructor after alloc. We call this method "Instance Constructor". The object ownership created by this method is the caller, the caller is responsible for the lifecycle of the caller. Specifically, the caller is responsible for creating and releasing the caller. The other method is the method starting with string-(class name after ns is removed) shown in line ②. It directly calls a class-level constructor through a class ", this method means that the ownership of the created object is not owned by the caller. The caller does not have the right to release the object. Otherwise, the object will be "zombie" due to the Transitional Release"

The alert object of the uialertview * type is not released after it is created. You only need to add the [alert release] statement code after [alert show]. The modified code

-(Void) tableview :( uitableview *) tableview didselectrowatindexpath :( nsindexpath *) indexpath {nsuinteger ROW = [indexpath row]; nsdictionary * rowdict = [self. listteams objectatindex: Row]; nsstring * rowvalue = [rowdict objectforkey: @ "name"]; nsstring * message = [[nsstring alloc] initwithformat: @ "you have selected the % @ Team. ", Rowvalue]; uialertview * Alert = [[uialertview alloc] initwithtitle: @ "select team" message: messagedelegate: selfcancelbuttontitle: @ "OK" Comment: Nil]; [alert show]; [alert release]; [Message release]; [tableview deselectrowatindexpath: indexpath animated: Yes];}

 

 

The above describes how to use analyze static analysis to find suspicious leak points, which are called "suspicious leak points", but these points may not be leaked, confirm whether these points are leaked and use the leaks and allocations trace templates in profile dynamic analysis tools instruments. analyze static analysis is just a theoretical prediction process. Start with product> profile. Select the leaks template from profile dynamic analysis tool.

Although the leaks template is selected in instruments, the allocations template is also added by default. Generally, the allocations template is used for memory analysis and can monitor the memory distribution, select the allocations template (area ① in the figure), and the area ③ on the right will display the memory usage line chart table as time changes, and the memory usage details will be displayed in Area ④, the allocation of objects just now. Click the leaks template (area ② in the figure) to view the memory leakage. If there is a red line in Area ③, there is a memory leakage, and area ④ shows the leaked objects.

The leakage occurs when you click tableview: didselectrowatindexpath: Method method in the table view. nscfstring objects are leaked, the nscfstring type is nsstring * type in nsfoundation. Click the triangle extension object in front of the leaked object to view its memory address, occupied byte, framework, and response method information.

Open the extended Details View, and you can see the trace stack Information on the right. here we apply the Code ourselves. You can click to enter our program code to open the corresponding code.

Code 77 is not a leak point, but the nsstring * type objects in it are leaked. Therefore, it can be concluded that the objects are not released after the message object, resulting in leakage. The modified code is as follows:

-(Void) tableview :( uitableview *) tableview didselectrowatindexpath :( nsindexpath *) indexpath {nsuinteger ROW = [indexpath row]; nsdictionary * rowdict = [self. listteams objectatindex: Row]; nsstring * rowvalue = [rowdict objectforkey: @ "name"]; nsstring * message = [[nsstring alloc] initwithformat: @ "you have selected the % @ Team. ", Rowvalue]; uialertview * Alert = [[uialertview alloc] initwithtitle: @ "select team" message: messagedelegate: selfcancelbuttontitle: @ "OK" Comment: Nil]; [alert show]; [Message release]; [tableview deselectrowatindexpath: indexpath animated: Yes];}

 

 

Add the [Message release] statement. Many people may also guess that the alert object (uialertview *) will leak, so they re-run the instruments tool and repeatedly click the cell test. No red line indicating Memory leakage is found! The instruments tool assumes that the alert object is not released and will not cause memory leakage. If we want to further evaluate its memory application, we can look at the line chart of the allocations template, the total memory usage for each click increases. This indicates that the alert object is not released. Although it is not very serious, it also increases the memory usage. Therefore, it is also necessary to release the alert object.

This is the solution to the memory leakage problem we introduced. In fact, the memory leakage is extremely complicated. The tool is used on the one hand and experience on the other. Improve experience, and then use tools to solve Memory leakage.

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.