游戏设计模式阅读笔记18——优化模式(对象池模式)

目录

一、意图

二、动机

三、对象池模式

四、实例代码

五、注意

        1.对象和池耦合的问题


一、意图

         放弃单独地分配和释放对象,从固定的池中重用对象,以提高性能和内存使用率。

二、动机

         比如粒子系统的调用,系统需要快速地生成成百上千个粒子。还需要保证创建和销毁这些粒子不会造成内存碎片。

         为游戏主机或者移动设备编程在许多方面比为普通计算机编程更像是嵌入式编程。内存紧张,压缩内存的管理器很难有效。在这种环境下,内存碎片是致命的。

         碎片意味着在堆中的空余空间被打碎成了很多小的内存碎片,我不是大的连续内存块。总共的可用内存也许很大,但是最长的连续空间可能难以忍受地小。

一个简单又有效的方法:在游戏开始时取一大块内存,然后直到游戏结束才去释放它。但是这要在游戏运行时创建和销毁事物的系统是不友好的。

使用对象池,就需要将一大块内存分出来,保持在游戏运行时不释放它。对于池中的对象的管理可以简单的构造和析构。

三、对象池模式

         定义一个池对象,其包含一组可重用对象。其中每个可重用对象都支持查询其状态,是否在被使用。池被初始化时,就创建了整个对象集合(通常使用一次连续的分配)。

        需要新对象,池子会返回一个不在使用中的对象,并改变其状态。

        1.适用场景

                1.需要频繁创建和销毁对象

                2.对象大小相仿

                3.在堆上进行对象内存分配十分缓慢或者会导致内存碎片

                4.每个对象都封装了像数据库或者网络连接这样昂贵又可以重用的资源。

        2.池中对象都被使用,无法在创建的解决办法

                1.增加池子大小。根据每个游戏场景需求和游戏内存来定。

                2.不创建新的对象。对于不重要的对象,或者不明显的对象可以考虑不再创建。

                3.强制干掉一个已有的对象。

        每个对象的内存大小是固定的。如果你的对象是大小可变的,你可以再将池子分成大小不同的池,大箱子给大行李,小箱子给小行李。

        重用对象不会自动清除数据,保证初始化代码将完全的初始化所有的数据。在池中对象不再使用后,需要清除它对其他对象的所有引用。

四、实例代码

        创建一个粒子系统的对象池

        对象池中有一个固定大小的数组。也可以使用动态大小的数组或使用由外部定义的模板变量。animate是粒子系统播放的函数。

        创建新粒子:

         找到可用粒子就返回,没有就不创建新的粒子。

        如果不想浪费时间查找空闲粒子。可以使用列表来管理他们。但这样就多了一个对象池同样大小的单独数组。

        或者通过修改粒子系统类:

 

        这里framesLeft表示粒子的状态,union的部分都是可重用的。next指针指向下一个未使用的粒子。 这个方法叫做freelist。unions的内存优化涉及到位压缩技术。

        freelist的对象池:

        追踪列表的头指针。

首次创建需要构建整个链表。

233333333可爱的作者,爱了爱了

        在粒子使用完后,管理状态。

        状态变化后放回空闲列表中。

五、注意

        1.对象和池耦合的问题

                1.对象与池耦合

                        实现更简单。能保证对象只能被对象池创建。C++中,就让池对象是对象类的友类,将对象的构造器设为私有。

                2.对象没有和池耦合

                        可以保存多种类型的对象。必须在对象的外部追踪“使用中”状态。

      

        

 

 

 

 

 

                   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值