IOS memory optimization and debugging skills (based on cocos2d Games)

Source: Internet
Author: User

Basic

1: image memory size Summary

A: Images: Large Memory users, especially mobile game image resources. Computing the usage of image resources in memory has become a frequent task for developers of j2s games. CoCoMo explains how to calculate the usage of images in memory: memory usage = width * height * pixel bytes, the number of pixel bytes varies by model.
For example, the memory usage of a 64*64 image on 7210 = 64*64*1.5 = 6144 (bytes) = 6 K. memory usage on S60 = 64*64*2 = 8192 (bytes) = 8 K. The number of pixel bytes varies by model. For example, 7210 is a 4096-color model, that is, 12-bit is used to represent a pixel. Therefore, 1.5 is multiplied, while S60 is a 65536-color model, 16 bits are used to represent a pixel, So we multiply by 2.

B: How to use instruments to view image memory in Xcode

If the simulator is used, the default screen is small, so the maximum image size is 1024*1024*4 = 4 M (1024 is the width and height of the image, 4 indicates that the image storage type is 4 bytes. That is, RGBA8888)

If you load the image, the memory is 4 MB. If you need rendering, you still need 4 MB of memory.

Loading is generally ** load (NSString *) filename,

Rendering is generally Node addChild (Node)


2: reference count

When the reference count increases: a: The alloc object will make the object reference count + 1

B: Call retain (For details, refer to the following examples)

-> For example, if you are a cocos2d user, you will see that addchild will increase the reference count of the subnode by 1.

-> The addObject of CCArray also makes the reference count of the element + 1

To sum up, you do not need to retain any elements or subnodes added to the combination. You only need to call the release

Reduction: Call release to make reference count-1 (For details, refer to the following examples)

-> The collection calls remove/removeChildByTag, and so on.

-> Call autorelease during creation. NOTE: If your object is a local object and you use autorelease when creating it,

If you do not have a retain when you exit the method, the object will be dealloc (reference count-1)

Official Website introduction:


You own any object you create by allocating memory for it or copying it.
Related methods: alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

If you are not the creator of an object, but want to ensure it stays in memory for you to use, you can express an ownership interest in it.
Related method: retain
If you own an object, either by creating it or expressing an ownership interest, you are responsible for releasing it when you no longer need it.
Related methods: release, autorelease
Conversely, if you are not the creator of an object and have not expressed an ownership interest, you mustnotrelease it.
3: References

I. IOS and image memory

On IOS, the image is automatically scaled to the Npower of 2. For example, a 1024*1025 image occupies the same memory as a 1024*2048 image. The formula for calculating the memory used by the image is: length * width * 4. In this case, the memory occupied by 512*512 is 512*512*4 = 1 M. Other dimensions, and so on. (Ps: the maximum size supported on IOS is 2048*2048 ).

2. cocos2d-x image Cache

The Cocos2d-x uses spriteWithFile or spriteWithSpriteFrameName when constructing an Sprite. Either way, the cocos2d-x loads the image into the cache. If the image is loaded for the first time, the image will be first loaded to the cache and then read from the cache. If the cache already exists, it is extracted directly from the cache, eliminating the need for loading.

The image cache is mainly processed by the following two classes: CCSpriteFrameCache and CCTextureCache.

CCSpriteFrameCache loads a spliced big image. Each small image is only a region in the big image. The region information is saved in the plist file. You can load the image to this region based on the name of the thumbnail.

CCTextureCache is a normal image cache. By default, all images directly loaded are stored in this cache to improve call efficiency.

Therefore, each time an image is loaded or a spliced image is loaded using plist, the entire image is loaded into the memory. If you do not release it, it will remain in use.

3. Rendering Memory.

Do not think that during memory computing, only the memory loaded into the cache can be computed. Take a 1024*1024 image as an example.

CCSprite * pSprite = CCSprite: spriteWithFile ("a.png ");

After calling the code above, you can see in the LEAKS tool that the memory is increased by about 4 MB. Then call

AddChild (pSprite );

At this time, the memory is increased by 4 MB. That is, if an image needs to be rendered, the memory occupied by it will be X2.

Let's take a look at the image loaded through plist. For example, the size of this large image is 2048*2048. To load a 32*32 small image

CCSpriteFrameCache: sharedSpriteFrameCache ()-> addSpriteFramesWithFile ("B. plist ");

At this time, the memory is increased by 16 MB (perspiration)

CCSprite * pSpriteFrame = CCSprite: spriteWithSpriteFrameName ("b1.png ");

B .png is 32*32 in size. If you want to increase the memory by a little bit, you can increase the memory by 16 Mb. That is, as long as a part of the rendering is completed, the entire image will be loaded together.

However, the situation is not so bad. If the rendered images are loaded again, the memory will not continue to increase. For example, an increase of 100 B. in another area of plist, the image memory is increased by 16 + 16 = 32 M, rather than increasing.

4. Release the cache

If the game has many scenarios, you can release all the memory in the previous scenario when switching the scenario to prevent the total memory from being too high.

CCTextureCache: sharedTextureCache ()-> removeAllTextures (); release all loaded images so far

CCTextureCache: sharedTextureCache ()-> removeUnusedTextures (); releases the CCTextureCache: sharedTextureCache ()-> removeTexture (); separately releases an image

The CCSpriteFrameCache and CCTextureCache release methods are similar.

It is worth noting that the release time is usually used to release resources during scenario switching. If you switch from scenario A to scenario B, the call sequence is B: init () ---->:: exit () ----> B: onEnter () if the switching effect is used, such as CTransitionJumpZoom: transitionWithDuration, the call sequence of the function is changed to B: init () ----> B: onEnter () ----> A: exit () and the second method overwrites the resources of the two scenarios, it is very likely that the memory will crash due to a tight diet.

Sometimes, when all resources are forcibly released, an exception occurs when an animation being executed is out of reference. You can call CCActionManager: sharedManager ()-> removeAllActions (); to solve this problem.

5. Memory Optimization

The optimization is to try to splice the image, so that the side length of the image is as long as possible to maintain the Npower of 2 and the installation is very full. However, it should be noted that images with logical relationships should be packaged in a large image as much as possible, and the distribution of layers should be considered during packaging. For rendering efficiency, CCSpriteBatchNode may be used. Images in the same BatchNode are all at the same level. Therefore, they must be packaged into different plist Layers Based on the hierarchical relationship of each image. Sometimes the memory and efficiency cannot be both at the same time. You can only try to balance it as much as possible.

Vi. Others

The memory limit of each generation of IOS devices is attached.

Recommended maximum memory size for devices

IPad2/iPhone4s/iphone4 170-180 mb 512 mb

IPad/iPod touch3, 4/iphone3gs 40-80 mb 256 mb

IPod touch1, 2/iPhone3g/iPhone1 25 mb 128 mb

The recommended memory is only the result of some tests. The available RAM is not more than half of the maximum memory. If the program exceeds half of the maximum memory, it may fail.

In addition, you can view the total memory of the simulator and the real machine in LEAKS. The result in the simulator is closer to the actual one.

7. Leakage

The main memory leakage methods I have encountered:
1. The most common one is to apply for a reference and forget to release it. Specifically, alloc, retain, copy, new, C's malloc, realloc, C ++'s new, etc. of OC are used, and there is no corresponding release, free, and delete. This is a one-way leak.
2. retain cycle. For the OC-based counting method, there may be a retain cycle. Two conditions: 1. In A, B retakes B, and B retakes A. Each of them increases the Count of each other. This ring can be changed to multiple layers, that is, A-> B, b-> C, C-> D ,.... z-> A. Of course, the more intermediate layers, the more difficult to detect. 2. The count reduction operation is performed in dealloc, while dealloc needs to be counted as 0 if it is called. These two conditions are added, leading to counting locking and Memory leakage.

Practical drills

How can I find memory leaks?

I. Search for tools

1. First, use Analyze build to view the memory warning in the category.
In general, we can find that the local variables forget the release, or the release is interrupted midway through.
2. Use the leak monitoring in Instruments directly.
After applying for the memory, there is no pointer pointing to this memory, which can be considered as a leak. This check usually detects this status.
3. Use mark heap of allocation in Instruments.
Perform repeated operations and mark the memory after each scenario ends. If the operation scenario is not leaked, the increase in memory should be 0. This check is used to detect which objects are added between mark points. In addition, it takes several times for the mark to be accurate. If you do not see the memory increase twice, you can find the problem.
In Instruments, you can see what objects exist, call history, and call stack. At this time, it is roughly determined that the object in the class has been leaked.

2. Heavy Load Method.
Although I know which class has been leaked, I sometimes don't know what the problem is. My own method is to reload the retain and release methods and add breakpoints if it is a self-compiled class. In this way, we can monitor where this object is retained, but it is not released.

How can I modify the memory leakage?

1. What do you need. If release is missing, add release. If release is missing, add free.
2. Use autorelease properly. For upper-layer events that are returned, or when there is a return or other interruption between the alloc object and the release. We recommend that you use autorelease.
3. Use assign properly. Retain cycle is essentially a redundant two-way retain. For example, you should determine which object is the root and which one is the branches and leaves. You do not need to manage the roots, but you only need to know where the root is. Therefore, the variables that are purely for positioning and attributes are changed to the assign method, such as delegate.

A very difficult leak I encountered in the game contributed here:

For cocos2d users who use CCMenu, and also rewrite the onExsit function in CCScene to detect some changes when leaving the scene. But I forgot to call super onExsit.

At this time, the CCMenu cannot be released because it has registered an event delegate. As a result, the CCMenu cannot be released. When loaded to other scenarios, events will always be wrong. This is the cause.

The solution is to call super onExsit. Because here he released delegate

Here is a main menu of the game.

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.