First, IOS and picture memory

On ios, the picture will be automatically scaled to a size of n to the power of 2.For example, a 1024 * 1025 picture uses the same memory as a 1024 * 2048 picture.The calculation formula for the memory occupied by pictures is:Length * width * 4. The memory occupied by such a 512 * 512 is 512 * 512 * 4=1m. Other dimensions and so on.(The maximum size supported on ps:ios is 2048 * 2048).

Second, cocos2d-x picture cache

cocos2d-x will use spritewithfile or spritewithspriteframename when constructing a sprite.cocos2d-x will load this image into the cache.If this image is loaded for the first time,Then it will load this picture into the cache first,Then read from the cache.If the cache already exists,Is taken directly from the cache,Eliminate the loading process.

Image caching is mainly handled by the following two classes:ccspriteframecache, cctexturecache

ccspriteframecache loads a large stitched image,Each small picture is just an area of ​​the big picture,These area information are saved in the plist file.When it is used, it only needs to be loaded into this area according to the name of the thumbnail.

cctexturecache is a normal image cache,All our directly loaded images will be placed in this cache by default,To improve calling efficiency.

So, loading one image at a time,Or when loading a mosaic through plist,Will load the entire image into memory.If you do n’t release it,That will always be occupied.

Third, rendering memory

Don't think thatWhen calculating memory,Just count the memory loaded into the cache.Take a 1024 * 1024 picture as an example.

ccsprite * psprite=ccsprite ::spritewithfile ("a.png");

After calling the above line of code,Can be seen in the leaks tool,Added about 4m of memory. And then call

addchild (psprite);

At this time, the memory increased by 4m. That is, a picture,If rendering is required,Then the memory it takes will be x2.

Look at the pictures loaded through plist,For example, the size of this large image is 2048 * 2048. Want to load one of 32 * 32 small pictures

ccspriteframecache ::sharedspriteframecache ()->addspriteframeswithfile ("b.plist");

At this time the memory increases by 16m (sweat)

ccsprite * pspriteframe=ccsprite ::spritewithspriteframename ("b1.png");

b.png size is 32 * 32, thinking that it is to add a little memory,But the actual situation is to increase 16m memory. That is, as long as a part of it is rendered,Then the entire picture is loaded together.

But the situation is not so bad,These already rendered pictures,If it loads again,Memory will not continue to rise,For example, another area of ​​100 b.plist is added,The picture memory still increased by a total of 16 + 16=32m, and will not continue to rise.

Fourth, cache releaseIf the game has many scenes,When switching scenes, you can release all the memory of the previous scene,Prevent total memory from becoming too high.

cctexturecache ::sharedtexturecache ()->removealltextures ();release all images loaded so far
cctexturecache ::sharedtexturecache ()->removeunusedtextures ();release pictures with a reference count of 1 cctexturecache ::sharedtexturecache ()->removetexture ();release a single picture individually
ccspriteframecache is similar to the method released by cctexturecache.

It ’s worth noting the timing of release,Generally release resources when switching scenes,If you switch from scene a to scene b, the order of the called functions is b ::init () ---->a ::exit () ---->b ::onenter (). If you use a switching effect, ,For example, functions like ctransitionjumpzoom ::transitionwithduration,Then the calling order of the function becomes b ::init () ---->b ::onenter () ---->a ::exit () and the second way will have two scenes Resources stack up,If not taken too much,It is likely to crash due to tight memory.

Sometimes when all resources are forcibly released,Will cause a running animation to lose its reference and pop up an exception,You can call ccactionmanager ::sharedmanager ()->removeallactions ();to resolve.

Five, memory management

1 Overview

cocos2d-x was originally ported from the objective c version of cocos2d. Therefore, in terms of memory management,Uses a reference counter method similar to nsobject,The relevant interface is placed in the ccobject class.

2. Reference counters-manual memory management

When ccobject and its subclasses are created,The reference count is automatically set to 1. Every time after calling retain, the reference count is +1. Each time release is called, the reference count is -1;if the reference count is 0, delete this directly.

The relevant interfaces are as follows:

// Number of references +1
virtual void ccobject ::retain (void);
// Number of references -1;if the reference counter=0, delete this;
virtual void ccobject ::release (void);
// helper method to quickly determine that the current object has only unique references
bool ccobject ::issinglerefrence (void);
// Returns the number of references
unsigned int ccobject ::retaincount (void);

Principle 1:Who generates (new, copy) who is responsible for release.


ccobject * obj=new ccobject;
obj->release ();

retain is used in pointer passing and assignment,He means to have.This is often used for pointer assignment.

Principle 2:Who retains and who is responsible for release.


obj->retain ();
obj->release ();

Principle 3:When passing assignments,You need to retain the parameter first, then release the original pointer, and finally assign it.(Note that because no self-assignment check is used here,So this group order cannot be wrong.)


void ccnode ::setgrid (ccgridbase * pgrid)
 cc_safe_retain (pgrid);
 cc_safe_release (m_pgrid);

3. Automatically release the pool-automatically manage memory

Principle 4:For objects using autorelease, don't worry about it,It will be released automatically after the end of each frame.

Related interfaces:

ccobject * ccobject ::autorelease (void);


ccobject * obj=new ccojbect;
obj->autorelease ();

Manage memory completely manually,Very tedious, cocos2d-x provides an automatic release pool ccpoolmanager. Place the object in the auto-release pool,At the end of each frame,The objects in the pool are automatically released.

4.ccnode node management

cocos2d-x uses nodes to form a tree,This tree is traversed when rendering.ccnode is the parent of all node classes,He uses a ccarray object internally to manage all his children,When an object is added as a child node,It is actually added to the ccarray object, and the retain method of this object is called at the same time. Similarly, when removed from the ccarray,The release method is also called.

Related interfaces:

virtual void addchild (ccnode * child);
virtual void addchild (ccnode * child, int zorder);
virtual void addchild (ccnode * child, int zorder, int tag);
virtual void removechild (ccnode * child, bool cleanup);
void removechildbytag (int tag, bool cleanup);
virtual void removeallchildrenwithcleanup (bool cleanup);

When switching scenes,The system will traverse the nodes of the entire tree,Make a release.

5. Static factory

There are a lot of static factory methods in cocos2d-x,Of these methods,They all called the autorelease function on this pointer. As these methods in ccsprite:

static ccsprite * spritewithtexture (cctexture2d * ptexture);
static ccsprite * spritewithtexture (cctexture2d * ptexture, const ccrect&rect);
static ccsprite * spritewithtexture (cctexture2d * ptexture, const ccrect&rect, const ccpoint&offset);
static ccsprite * spritewithspriteframe (ccspriteframe * pspriteframe);
static ccsprite * spritewithspriteframename (const char * pszspriteframename);
static ccsprite * spritewithfile (const char * pszfilename);
static ccsprite * spritewithfile (const char * pszfilename, const ccrect&rect);
static ccsprite * spritewithbatchnode (ccspritebatchnode * batchnode, const ccrect&rect);

These methods are implemented internally:memory allocation, initialization, setting autorelease. Use static factories to generate objects,Can simplify the code,Is the officially recommended method.

6.cache mechanism class

There are some cache classes in cocos2d-x, these are all singleton class managers.


These caches also use the retain and release methods internally to prevent these resources from being released.

Using these caches, we can save some pre-loaded resources,Call it at a convenient time,To bind to some objects.Note that when these caches change,Is not deleted automatically,Need to manually call the purgexxxx method to clean up.

  • Previous PHP emergency code to prevent website from being attacked
  • Next Play WAV audio files in PowerShell
  • Trends