游戏中内存优化总结

作者:陈劲灿 编辑日期: 2018年1月11日 22:11 阅读量: 392 分类: gameengine

游戏中的内存优化

进行游戏内存优化可以保证游戏可以供更多的用户使用。

游戏中内存占用分析

一、 纹理

纹理占游戏占用内存的很大一部分,通常纹理应用的地方有UI、场景、人物、动画、特效等。

如何计算纹理占用内存?

先来看看基础知识:1Byte = 8bits, 纹理中一个像素通过RGBA进行颜色的表示。R(红)、G(绿)、B(蓝)、A(Alpha透明通道)。

RGBA8888: 代表的是R、G、B、A分别占用8位、也就是分别占用一个字节。所以一个RGBA8888表示的像素所占用内存为4个字节。 RGBA4444: 占用4个字节 RGB565: 这里没有Alpha通道,并且R占5位、G占6位、B占5位。RGB561占用2个字节

PNG8: 占用1个字节、可以表示透明度不过只能表示256色 PNG24: 占用3个字节或者4个字节,不能表示透明度,不多可以表示更多颜色。 PNG32: 占用4个字节可以表示透明度、以及更多的颜色,不过占用内存大。

ETC1\ETC2: 占用0.5个字节, 为Android硬件支持纹理格式, 不过ETC1 不包含透明通道。 PVR.CCZ: 占用0.5个字节,为iOS设备硬件支持纹理格式。

一张1024 x 1024的RGBA8888图片所占用的内存为 1024 1024 4 = 4MB 一张1024 x 1024的PVR.CCZ图片所占用的内存为 1024 1024 0.5 = 0.5MB

如何通过纹理格式以及平台来选择纹理?

由上面说的纹理基础知识以及纹理内存计算公式,我们可以知道即节约纹理占用大小,还不需要读取纹理后解压的纹理是ETC1\ETC2,以及PVR.CCZ

所以Android平台推荐使用ETC1\ETC2、iOS平台使用PVR.CCZ格式。 不过由于ETC1不支持透明通道,所以一般推荐使用ETC1 + Alpha的模式,这样可以解决透明度问题,不过在读取纹理时会增加内存消耗。

纹理优化的工具

1、如果不想使用ETC1\PVR等格式 可以将png32图片压缩成png8格式,这样可以减少包的体积,不过不能减少显存的大小。 2、面向iOS平台可以通过TexturePacker等工具将png32转为PVR.CCZ 格式。 3、面向Android平台可以通过ARM Mail Texture Compress 将png32转为ETC1 + Alpha的格式。

二、 音频

一般来说音频文件占用的游戏内存不会很大,这里主要有两个部分, 一个是常驻内存的音乐音频文件、一个是边读边播的音效文件。

游戏中常用的音频格式mp3、wav、ogg、aiff等。

Android中主要使用的是mp3、ogg格式 iOS中主要使用mp3、ogg、aiff等格式。 Windows中主要使用wav格式。

优化音频使用的内存主要是去除掉那些不常用,并且常驻内存中的音频数据。 顺便对于mp3格式的音频文件来说不适合做循环音效,ogg更加适合。

三、配置数据

游戏中的配置数据一般来自策划的配置,所以这些配置和游戏内容息息相关,一般都会常驻于内存当中。 常见的游戏配置数据格式有 json、xml、自定义格式二进制文件、lua配置等。

通常来说将策划的配置数据导出为二进制格式是最为节省包体大小的方式,并且可以通过对二进制加密保护游戏内的配置数据。 不过这对于文件的调试可读性大打折扣。

在游戏的开发阶段可以将配置文件导出为json或者xml增强文件的可调试性。而在游戏的发布阶段将配置数据导出为二进制或者二进制的json,xml格式。这样可以对配置数据进行磁盘压缩。

由于配置数据读取到内存中会在游戏的生命周期从开始到结束。如何保证配置数据的内存所占用的大小越小越好?

  1. 可以通过数据结构对配置数据中的索引进行优化。降低内存中数据所占的大小。
  2. 可以针对不是全局的数据配置进行,即用即加载不需要进行缓存的策略降低内存使用。
  3. 对于同一时间可能一次性加载多张数据配置的节点,可以通过分帧加载的方式,防止内存出现很高的峰值被操作系统kill。
四、游戏逻辑

一般来说游戏逻辑有几个点

  1. 游戏战斗相关的逻辑。 这里面应该算是游戏中最有可能达到内存峰值点的地方。主要是游戏人物模型、NPC、场景、特效等占用的内存。不过这些内存绝大多数都是纹理占用的。 人物相关的更新、特效计算等才是游戏逻辑占用的内存。比如当一个游戏人物还未出现在游戏的界面中,则不应该对该人物的状态进行进行显示。

  2. 游戏界面渲染相关的逻辑。 游戏中的页面渲染一般通过事件的方式将数据发送给需要数据的人。 页面渲染主要的内存优化点:

  3. 尽量将页面的层级数降低。
  4. 对于列表类、翻页类容器来说需要做优化,尽可能少的显示元素。
  5. 对于UI界面来说尽可能的使用通用的纹理资源,共用以达到降低内存的目的。
  6. 页面中的逻辑运算应该精简。因为主要目的是进行数据的刷新。

  7. 游戏网络相关的逻辑。 客户端和服务器交互通过一定的协议进行相互传递数据RPC,网络通信中如果收发的数据量大会引起两个方面的问题,数据量过大会引起接收时间过长响应缓慢,页面刷新也会出现长时间的卡顿。 另外一方面需要将传输的数据进行解析的时间也会过长。

所以一般建议此处的网络交互数据量进行传输大小的限制。

  1. 对于游戏中有多种语言交互的场景需要注意。 1、如Unity中C# 与 Lua之间的交互 2、Cocos2dx中C++ 与Python之间的交互

在不用的语言调用的时候需要注意

  1. 尽量使用每一个语言自己的内存管理方式。
  2. 分析哪些是消耗内存的地方,进行单独的优化。
五、游戏引擎

对于游戏引擎来说,主要的工作是有游戏引擎工程师来做的, 我们主要需要做的就是不乱用游戏中的api,保证自己不出现内存错误。


上一篇
下一篇
TensorFlow的深度学习文章->_->训练模型的保存与模型的还原
游戏内的数据保存格式对比