一个CCSprite所需要耗费内存分析

2024-01-30 21:38

本文主要是介绍一个CCSprite所需要耗费内存分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



Just copy from

http://www.cocoachina.com/bbs/simple/?t56479.html


一个CCSprite所需要耗费内存分析

加载一张图片的过程 所发生的函数:
1.[CCSprite spriteWihtFile:@"xxxx"];  //函数内部用 CCTexureCache  创建一个CTexture2D对象.

2.[CCTexureCache sharedTexure] addImage:@"xxxx"];  //首次创建,则加载图片创建纹理,并缓存.
UImage* img =  [UImage initWithContentsOfFile:@"xxxx"];//需要一些内存,这些内存是暂时的.创建纹理后被释放.
[CCTexure2D initWithImage:img];  
//这个函数内部会转换图片的像素格式,并向OpenGL分配纹理需要的空间.
//分配空间大小的规则是: (2^n  x 2 ^n x 4)BYTE (
例如 1024*1024 图片占4M = 4*10^6 b 。 对于16位色-每像素16位颜色 系数是2 即2M=2*10^6b) ,例如:加载一张128*128的图片 和 加载一张 128 * 100 或 99 * 99 的图片需要的内存大小相同。
//如果加载一张513*129的图片,就会以1024*512来分配内存。
//
所以这里用ZWoptex来排列所有非规则( 大小不为 2^n  x 2 ^n )小图片是比较省内存的. 其实是这个

——————————————

再看看经过plist加载的图片,例如这张大图尺寸为2048*2048。想要加载此中的一张32*32的小图片
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("b.plist");

此时内存增加16M (汗)

CCSprite *pSpriteFrame = CCSprite::spriteWithSpriteFrameName("b1.png");
b.png 大小为32*32 ,想着也便是增进一点点内存,可实践情况是增长16M内存。也就是只有渲染了此中的一局部,那末整张图片都要一块儿被加载。

 

但是环境不是那末的糟糕,这些曾经渲染的图片,假定再次加载的话,内存是不会再持续抬高的,比方又添加了100个b.plist的另一个区域,图片内存照旧共增加16+16 = 32M,而不会继续上升。

————————————————

3.[CCTexure2D initWithData:(void*) xx]; //这个函数主要是对函数2转换后的位图数据(RGBXXXX),进行纹理加载.
//这里用到了OpenGL函数的 glGenTexures(产生一个纹理对象) glBindTexture(绑定为OPENGL当前纹理) glTexImage2D(给纹理加载位图数据) 
//其中glTexImage2D内部会调用 gfxAllocateTextureLevel 函数分配内存.如果是1024*1024则是4M的大小(图片占用内存大小的共计的公式是;长*宽*4). Instruments可以监控到 内存的分配函数gfxAllocateTextureLevel.

//*********  以上是加载一张纹理的大小 ****************


//*********  以下是绘画一张纹理的大小 *****************
//OpenGL绘画纹理还需要消耗内存.
在CCSprite 的 draw 函数中:
glDrawArrays 函数内部调用 gldLoadTextureLevelBuffer . Instruments可以监控到 内存的分配函数 gldLoadTextureLevelBuffer .
这里需要的内存为:实际绘画纹理大小的规则大小.
例如:
一张大小为800*600的图片 需要 1024*1024*4 = 4M 内存用于纹理加载。
如果只绘画这张图片的 某个 28*28大小的 区域, 那么还需要一个 32 * 32 *4 = 4K 大小的内存. 共用4.004M内存
如果需要绘画800*600的全部区域,则需要1024*1024 = 4M内存. 共用8M内存。也便是,一张图片,若是必要渲染的话,那它所占用的内存将要X2。


//*********  内存优化 *****************

假定游戏有不少场景,在切换场景的时刻可以把前一个场景的内存所有开释,预防总内存过高.

CCTextureCache::sharedTextureCache()->removeAllTextures(); 拘留到今朝为止所有加载的图片

CCTextureCache::sharedTextureCache()->removeUnusedTextures(); 将引用计数为1的图片开释掉CCTextureCache::sharedTextureCache()->removeTexture(); 单独囚系某个图片


1.纹理缓存 有个 purgSharedTexureCache可以删除当前纹理缓存,释放当前纹理缓存,但其他CCSprite有对纹理的引用,所以这个函数不会真的释放内存,而且再次加载已经存在的纹理的时候又需要大量内存. 
不建议使用 purgSharedTexureCache. removeAllTextures也是一样的情况.

2.使用removeUnusedTexutres 来释放已经没有其他对象引用的纹理.

3.非重复性图片不建议使用CCTexureCache来缓存纹理.直接用CCTexture2D创建纹理. 比如,一些内存资源比较紧缺的设备,处理非重复性图片(某些单一对话框背景)不缓存.


CCDriectro中 每次去渲染的时候!都会去查看内存释放池的是否有内存计数为0的对象!如果有的话!就会去清理掉!释放内存!(每次渲染引用计数加1)


如场景切换  在内存吃紧的情况下 我们可以选择 先清理一下缓存!

1)调用 CCDirector::sharedDirector()->purgeCachedData() 清空缓存。
2)新建场景。
3)调用 CCDirector::sharedDirector()->replaceScene(this)
 替换新场景。




这篇关于一个CCSprite所需要耗费内存分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/661623

相关文章

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

MySQL表锁、页面锁和行锁的作用及其优缺点对比分析

《MySQL表锁、页面锁和行锁的作用及其优缺点对比分析》MySQL中的表锁、页面锁和行锁各有特点,适用于不同的场景,表锁锁定整个表,适用于批量操作和MyISAM存储引擎,页面锁锁定数据页,适用于旧版本... 目录1. 表锁(Table Lock)2. 页面锁(Page Lock)3. 行锁(Row Lock

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动