一、定义:

关于U3D内存优化,一直是游戏开发者头疼的事情,由于在项目中我们会频繁地创建和销毁一些对象,例如:怪物模型或者是UI预设体,但是,部分对象在游戏中是会频繁出现的,例如战斗中的小怪物,假如每次都在使用的时候创建新对象,使用完毕后又直接销毁,这样对于游戏的内存消耗是很巨大的。

设想一下,我们是否能做一个池子,将一些常用的对象在创建之后放入池中,每次使用都直接从池子中查找获取,这样在提高对象利用率降低重复创建对象时的内存消耗的同时,对于性能提高有很大的帮助,这样的池子就是我们所要说的——对象池

对象池——就是将对象存储在一个池子中,当需要时再次使用,而不是每次都实例化一个新的对象。


二、使用对象池有几个注意点:

1.虽然对象池可以优化对象利用率,但是对象池也不能无限地存储对象,这样对于内存占用也是急剧增加,应该通过限制池子上限,并通过统计获取使用频率较低的对象并剔除,从而动态地收缩对象池;

2.对于重复使用的对象,在对象池中应该处理好对象重置(reset)的操作;

3.假如在多个线程中同时访问统一对象池,要处理好线程安全的问题。

三、实践:

关于对象池的内存优化,我们可以参考内存池的设计模式:内存池设计与实现

具体如何设计对象池,我们可以通过从AssetStore获取成熟的插件,例如:

PoolManager,具体使用方法:Unity3D研究院之初探PoolManager插件(七十四)

当然我们也可以设计自己的对象池框架:Unity3D内存管理——对象池(Object Pool)

具体步骤:

1.将插件.unitypackage包导入工程中;

2.在Hierachy中新建一个Empty对象,选中该Empty对象,然后选择菜单栏的Component—>Path-o-logical—>Pool Manager—>Spawn Pool:

3.完成上述步骤后,在Empty对象下会绑定一个Spawn Pool组件,接下来我们就需要进行基本的信息设置:

同一个对象池可以存放不同预设体,每个预设体我们都可以为其创建一个类型栏,同一预设体创建出来的对象归属于同一栏。

4.Spawn中各个属性的作用:

PoolName:缓存池的唯一名称。

MatchPoolScale:勾选后实例化的游戏对象的缩放比例将全是1,不勾选择用Prefab默认的。

MachPool Layer:勾选后实例化的游戏对象的Layer将用Prefab默认的。

Don’t Reparent:勾选后实例化的对象将没有父节点,通通在最上层,建议不要勾选。

Don’t Destroy On Load:这个就不用我解释了吧?切换场景不释放。

Log Messages: 是否打印日志信息

Pre-Prefab Pool Options :缓存池列表,意思就是缓存列表里面可以放各种类型的Prefab。右边有个 “+”按钮点击就添加每个类型的Prefab了

prefab:可以直接把工程里的Prefab直接拖进来。

preloadAmount:缓存池这个Prefab的预加载数量。意思为一开始加载的数量!

preloadTime:如果勾选表示缓存池所有的gameobject可以“异步”加载。

preloadFrames:每几帧加载一个。

preloadDelay:延迟多久开始加载。

limitInstance:是否开启对象实例化的限制功能。

limit Amount:限制实例化Prefab的数量,也就是限制缓冲池的数量,它和上面的preloadAmount是有冲突的,如果同时开启则以limitAmout为准。

limitFIFO:如果我们限制了缓存池里面只能有10个Prefab,如果不勾选它,那么你拿第11个的时候就会返回null。如果勾选它在取第11个的时候他会返回给你前10个里最不常用的那个。

cullDespawend:是否开启缓存池智能自动清理模式。

cull Above:缓存池自动清理,但是始终保留几个对象不清理。

cull Delay:每过多久执行一遍自动清理,单位是秒。从上一次清理过后开始计时

cullMaxPerPass:每次自动清理几个游戏对象。

自动清理:就是当池子里面的对象setActive(false)也就是目前不用的时候,poolManager会根据上述参数自动清理这些对象,清理也就是Destroy()掉。

active变为true或false是由Spawn和Despawn方法决定的!

limitInstance是否开启(打钩)的区别:

不开启情况:假如此时preloadAmount为1,如果用户想要每隔5秒去Spawn一个缓冲池中的对象,那么当加载第二个prefab对象的时候,缓冲池会再创建一个此对象,如果程序再Spawn,那么还会在产生一个这样的对象,就这样一直产生下去,Spawn几次就产生几个对象!

(粒子系统:循环时:Spawn几次,就会产生几个对象,不循环时(循环结束状态为false):会再产生一个对象,如果此时的Spawn速度特别快,并且检测不到前面的对象状态为false,那么可能会产生多个对象,直到检测到前面的几个对象有false状态,那么产生对象到此为止,程序在此几个对象之间来回Spawn!)

开启情况:

此时Limit Amount为1

limitFIFO勾选:那么程序永远使用的是预加载对象,而不会再产生其他对象!当加载第二次的时候,即使第一个对象处于true状态,也使用它,即操作第一个对象!(粒子系统为循环或者不循环时,效果和这一样)

limitFIFO不勾选:那么程序永远使用的是预加载对象,而不会再产生其他对象!当加载第二次的时候,那么必须等第一个对象变为false状态,才能使用它!如果过了5s,第一个对象还没变为false状态,那么程序会报错!(粒子系统为循环:会循环下去,只有一个预加载对象,不报错,不循环时:等上一个变为false才能进行第二次,只有一个预加载对象,不报错!)

如果limit Amount数量大于1,为10的话

limitFIFO勾选:永远只有10个对象产生,当加载第11个对象时,如果前十个对象没有一个active为false状态,那么程序会选择不常用的那个,从而避免报错!

limitFIFO不勾选:永远只有10个对象产生,但是当加载第11个对象时,如果前十个对象没有一个active为false状态,那么程序会报错!

(粒子系统,永远只有10个对象,不报错!)

5.设置完以上参数之后,我们开始在代码中进行对象添加到对象池和从对象池中取出对象的操作:

a. 获取对象池:

private SpawnPool mActors_Pool;

mActors_Pool = PoolManager.Pools["ActorsAndBullets"];

b.获取对象池中对象的方法:

Transform bulletPrefab = mActors_Pool.prefabs["Bullet"];
Transform bullet = mActors_Pool.Spawn(bulletPrefab);

c.销毁对象池中对象的方法:

mActors_Pool.Despawn(bullet);

d.全部销毁的方法:

mActors_Pool.DespawnAll();

Unity3D 内存优化(一)对象池相关推荐

  1. Unity3D游戏开发之类对象池优化秘籍残篇

    翻开秘籍第一页: 问: 什么是类对象池? 剑之初: 游戏中,我们常常会遇到频繁得创建和销毁大量相同对象的场景.如果我们不做任何的特殊处理,这种场景会出现两个性能问题--大量的内存碎片以及频繁的分配内存 ...

  2. Unity程序优化之对象池

    对于做程序的朋友来说优化是一个避免不了的话题,对于程序的优化可以从两个方面来入手,一个是CPU方面的优化,一个是GPU的优化.对于CPU与GPU的作用简单理解的话你可以暂时当做CUP是处理计算的.GP ...

  3. Java 程序优化之对象池

    对象池概念: 如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类都一些实例保存到一个"池"中,待需要使用的时候直接从"池"中获取.这个" ...

  4. 从入门到掉坑:Go 内存池/对象池技术介绍

    作者:deryzhou,腾讯 PCG 后台开发工程师 Go 中怎么实现内存池,直接用 map 可以吗?常用库里 GroupCache.BigCache 的内存池又是怎么实现的?有没有坑?对象池又是什么 ...

  5. redis存储对象_redis内存优化总结

    本文主要参考<>一书,主要分为以下六个部分: 1.redisObject对象 2.缩减键值对象 3.共享对象池 4.字符串优化 5.编码优化 6.控制key的数量 一. redisObje ...

  6. Unity3D 对象池 静态预制件与动态单体

    Unity3D 对象池 静态预制件与动态单体 效果 整体思路 静态预制件对象池 对象池接口 对象池接口继承类 动态单体对象池 游戏里为了利用内存资源一般对象池是用的比较多 这里总结了两版对象池. 请结 ...

  7. 【Python】学习笔记总结5(Python垃圾回收及内存优化)

    文章目录 五.Python垃圾回收 1.引用计数(主) 2.GC负责的主要任务 3.标记-清除 4.引用计数不能回收的案例分析 5.分代收集 6.GC的阈值 7.GC垃圾回收自动触发机制 7.内存优化 ...

  8. redis的内存优化【转】

    Redis所有的数据都在内存中,而内存又是非常宝贵的资源.对于如何优化内存使用一直是Redis用户非常关注的问题.本文让我们深入到Redis细节中,学习内存优化的技巧.分为如下几个部分: 一.redi ...

  9. 池式结构:对象池(Object Pool)

    本文是对 http://gameprogrammingpatterns.com/object-pool.html 的原创翻译.部分地方使用意译,不准确的地方请各位指证. 一.对象池的意义 通过重新使用 ...

最新文章

  1. 求表达式 f(n)的结果
  2. 贾扬清、Alex Smola、Julia创始人等大咖齐聚,WAIC开发者日共话AI未来
  3. 一文全览,深度学习时代下,复杂场景下的 OCR 如何实现?
  4. python多线程并行编程_Python并行编程(二):基于线程的并行
  5. 共享锁和排它锁的用法
  6. python 放射 水平_基于Python的放射性核素大气扩散程序初步开发与验证
  7. php代理请求失败,http请求失败有哪些原因
  8. ubuntu20.05安装vmware workstation 16,踩坑:GLib does not have GSettings support.
  9. 实用的手机app商城购物网站模板源码
  10. 获取mac最高root权限登录系统
  11. 基于股票数据的多元线性回归分析
  12. mysql insert 写法_mysql中insert into语句的6种写法(上)
  13. 华为u8500在usb模式下logcat无法打印信息
  14. 教你使用GitHub搭建个人网站
  15. <C++>初识多态,剖析virtual关键字
  16. 如何强制关闭mac后台程序
  17. jfinal与bootstrap的登出实战
  18. Linux 虚拟鼠标,键盘 之一。
  19. opencv漫水填充算法floodfill
  20. 「seo目录」白帽SEO是什么一天工作内容

热门文章

  1. java计算机毕业设计web实验室课表管理系统源码+mysql数据库+系统+lw文档+部署
  2. java计算机毕业设计郑工校园二手交易平台网站源程序+mysql+系统+lw文档+远程调试
  3. TWS耳机哪个品牌好用?好用的TWS耳机推荐
  4. Arch LVM (简体中文) -翻译版
  5. 【技术美术图形部分】图形渲染管线3.0-光栅化和像素处理阶段
  6. 计算机辅助工程具体应用,计算机辅助工程应用及展望.pdf
  7. qimo linux 中文,DoudouLinux一个有趣的Linux发行版为孩子们 | MOS86
  8. 「网络流 24 题」5.圆桌聚餐
  9. 怎么把文件同步到服务器,把文件同步到服务器上
  10. 外观设计的基本功能与产品特点