Contents

Tips For Memory Management in Objective-C

 

1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 5.00 out of 5)
Loading...

 

Pham Van Hoang, hoangk55cd@gmail.com, is the author of this article and he contributes to RobustTechHouse Blog

 

Introduction

Managing memory is very important and necessary step for any programming language, especially for devices that run on a limited amount of memory such as mobile phones and smart watches. Since iOS5, Apple has introduced Automatic Reference Counting (ARC) that makes automatic memory management possible for Objective-C objects, simplifying a developer’s job from having to manage the memory manually. However, ARC is different from Garbage collection and does not impose runtime memory model as Garbage collection does. Therefore, even with ARC, memory issues can still happen and can crash your app when system is in a state of low-memory. In this article, we will introduce you some tips to manage more memory efficiently.

 

Memory Management Tips

Observe Low-Memory Warnings And Respond To It Immediately

When a system is in low-memory, it will dispatch a warning to your app. Low-memory warning is your opportunity to immediately free up any unnecessary memory hogging routines such as caches and images. If you fail to response to these warnings, your app will be likely to be terminated by the OS. The system that delivers memory warnings to your app uses the following APIs :

  • TheapplicationDidReceiveMemoryWarning: method of Appdelegate.
  • ThedidReceiveMemoryWarning method of the UIViewController
  • TheUIApplicationDidReceiveMemoryWarningNotification notification.

If you need a way to trigger a memory warning so that you can write and test your memory cleanup code in your app, Xcode provides an option to simulate memory warning without having to write any code. You just need to click on Hardware > Simulate Memory Warning and Xcode will do the rest.

Avoid Strong Cycle (Strong Reference Cycles Between Class Instances)

This is quite a common mistake for developers and it can cause a memory leak (a piece of memory that has lost tracked and would never be deallocated by program). To understand more about the strong cycle, we will look at how ARC deallocates an object. In Apple document:

“ARC will not deallocate an instance as long as at least one active reference to that instance still exists. To make this possible, whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a strong reference because it keeps a firm hold on that instance, and does not allow it to be deallocated for as long as that strong reference remains.“

This problem occurs when one object has a ‘strong’ pointer to another and the target object has a ‘strong’ pointer back to the original. When all other references to these objects are set to nil, they will still continue to be referenced to one another and will not be deallocated. This can also happen by a chain of objects that might have the last one in the chain referring back to an earlier object.

Here is an simple example:

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_01

In this example, we have a class Person and a class Apartment. A person has an apartment called unit4A. And in object Apartment we have a tenant link to john.

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_02

Now you will quickly see what called Strong cycle since Person instance has strong reference to Apartment instance, and Apartment instance has strong reference to Person instance.

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_03

 

When we attempt to deallocate these objects by set two instances john = nil and unit4A = nil, the reference counts do not drop to zero. Therefore, the instances are not deallocated and they will stay in the memory until either system or user terminates the application.

To fix the problem, you need to add weak property in the tenant reference since weak reference does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance.

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_04

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_05

You can see more information on how to use the weak reference here (do note that the example is written in swift language but it is very easy to understand).

 

Using Autorelease Pool Blocks

An autorelease pool block is marked using @autoreleasepool. You should consider using @autorealease in your program in the following cases (based on recommendations from Apple):

  • If you create a second thread, you must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects.
  • If you write a loop that creates many temporary objects.

You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application, especially for convenience methods.

Let’s try this example:

- (void)viewDidLoad {
    [super viewDidLoad];

    for (int j = 0; j < 4; ++j)  {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
               UIImage *image = [UIImage imageNamed:@"test_image"];
                NSLog(@"%@", image.description);
            }
        }
    }
}

 

 

If you run the allocations instruments, you will see an allocations graph as following:

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_06

But if you remove the @autoreleasepool, you’ll see that peak memory usage is much higher:

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_07

See more about @autorealeasepool in apple document here

 

Reduce Your App Memory Footprint

Keeping your app in a low memory footprint gives you more room for expanding your app later and makes your app runs more smoothly. Here are some recommendations to reduce your app memory footprint:

  • Load resouces lazily: You should load resouces such as images, audios only at a time when they are needed. This helps to mitigate the problem of insuffcient memory instead of loading all your resources at once. In addition, if you end up not using the resources, loading it wastes memory for no purpose.
  • Use Core Data or SQLite for large data sets: As referred to by apple: “If your app manipulates large amounts of structured data, store it in a Core Data persistent store or in a SQLite database instead of in a flat file. Both Core Data and SQLite provides efficient ways to manage large data sets without requiring the entire set to be in memory all at once”.

 

Debugging App Memory

Override dealoc method

One of the good ways to see if certain object or viewcontroller is being deallocated is to override dealoc method.

-(void)dealloc
{
   NSLog(@"viewcontroller is being deallocated");
}

 

 

In objective-C, when an object is about to deallocate, it will send a message to dealoc function. By adopting this function, you will see if the object is actually deallocated or not.

 

Using the debugger and breakpoints

This is quite a fundamental debugging concept when using Xcode IDE to stop the running program at some certain points to investigate thestate of an object. It’s helpful if you can have an idea where the error might appears.

TIPS FOR MEMORY MANAGEMENT OBJECTIVE-C_08

Performing Static Code Analysis

Static analysis is a mechanism where a collection of techniques in IDE are used to analyze your source code to find potential bugs in project such as leaking allocated memory, logic flaws etc. This is a good step you should do before running the app or pulling out instruments to test the application.

  1. Choose Product > Analyze.
  2. In the issue navigator, select an analyzer message.
  3. In the source editor, click the corresponding message.
  4. Use the pop-up menu in the analysis results bar above the edit area to study the flow path of the flaw.
  5. Edit the code to fix the flaw.

Using Instruments

Instruments is your best friends when it comes to tracking down problems in your source code; and finding memory problems in your app, such as leaks, abandoned memory, and zombies during runtime. It is a very powerful and flexible performance-analysis and testing tool that ispart of the Xcode tool set. Within the Instruments app, there are many kinds of instruments such as Allocations, Leaks, Core Animation, Energy Diagnostics and Time Profiler. To track memory problems, I recommend that you to go and check out the ‘Allocations instrument and Leaks instrument’.

Apple’s document on Instruments  are here

 

C0nclusion

I hope that the tips above will help you manage memory in your apps more efficiently. If you have any questions, please leave the comments below. Thanks!

 

Reference

Apple – Performance Tips

Apple – About Memory Management

7 foolproof tips for iOS memory management using Swift and Objective-C

Memory Management Policy (Non-ARC the old way)

Automatic Reference Counting Swift (examples of cycles) Objective-C Memory  Management Essentials – Gibson Tang & Maxim Vasilkov

 

Brought to you by the RobustTechHouse team.  If you like our articles, please also check out our Facebook page.

Recommended Posts
Comments
  • fallout 76 hacks

    Some truly wonderful content on this web site , appreciate it for contribution.

Contact Us

We look forward to your messages. Please drop us a note for any enquiries and we'll get back to you, asap.

Not readable? Change text. captcha txt
An in-depth look at the rise of mobile banking _01Review of Shopee App_Cover