unity游戏mono内存管理及泄漏

unity游戏mono内存管理及泄漏

ID:35515560

大小:168.55 KB

页数:7页

时间:2019-03-25

unity游戏mono内存管理及泄漏_第1页
unity游戏mono内存管理及泄漏_第2页
unity游戏mono内存管理及泄漏_第3页
unity游戏mono内存管理及泄漏_第4页
unity游戏mono内存管理及泄漏_第5页
资源描述:

《unity游戏mono内存管理及泄漏》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、内存是手游的硬伤——Unity游戏Mono内存管理及泄漏WeTest导读内存是游戏的硬伤,如果没有做好内存的管理问题,游戏极有可能会出现卡顿,闪退等影响用户体验的现象。本文介绍了在腾讯游戏在Unity游戏开发过程中常见的Mono内存管理问题,并介绍了一系列解决的策略和方法,无论是游戏还是VR应用,内存管理都是其研发阶段的重中之重。什么是Mono内存对于目前绝大多数基于Unity引擎开发的项目而言,其托管堆内存是由Mono分配和管理的。“托管”的本意是Mono可以自动地改变堆的大小来适应你所需要的内存,并且适时地调

2、用垃圾回收(GarbageCollection)操作来释放已经不需要的内存,从而降低开发人员在代码内存管理方面的门槛。Unity游戏在运行时的内存占用情况可以用下图表示:目前绝大部分Unity游戏逻辑代码所使用的语言为C#,C#代码所占用的内存又称为mono内存,这是因为Unity是通过mono来跨平台解析并运行C#代码的,在Android系统上,游戏的lib目录下存在的libmono.so文件,就是mono在Android系统上的实现。C#代码通过mono解析执行,所需要的内存自然也是由mono来进行分配管理,

3、下面就介绍一下mono的内存管理策略以及内存泄漏分析。Mono内存管理策略Mono通过垃圾回收机制(GarbageCollect,简称GC)对内存进行管理。Mono内存分为两部分,已用内存(used)和堆内存(heap),已用内存指的是mono实际需要使用的内存,堆内存指的是mono向操作系统申请的内存,两者的差值就是mono的空闲内存。当mono需要分配内存时,会先查看空闲内存是否足够,如果足够的话,直接在空闲内存中分配,否则mono会进行一次GC以释放更多的空闲内存,如果GC之后仍然没有足够的空闲内存,则mo

4、no会向操作系统申请内存,并扩充堆内存,具体如下图所示。通过上文可知,GC的主要作用在于从已用内存中找出那些不再需要使用的内存,并进行释放。Mono中的GC主要有以下几个步骤:1.停止所有需要mono内存分配的线程。2.遍历所有已用内存,找到那些不再需要使用的内存,并进行标记。3.释放被标记的内存到空闲内存。4.重新开始被停止的线程。除了空闲内存不足时mono会自动调用GC外,也可以在代码中调用GC.Collect()手动进行GC,但是,GC本身是比较耗时的操作,而且由于GC会暂停那些需要mono内存分配的线程(

5、C#代码创建的线程和主线程),因此无论是否在主线程中调用,GC都会导致游戏一定程度的卡顿,需要谨慎处理。另外,GC释放的内存只会留给mono使用,并不会交还给操作系统,因此mono堆内存是只增不减的。Mono内存泄漏分析Mono是如何判断已用内存中哪些是不再需要使用的呢?是通过引用关系的方式来进行的。Mono会跟踪每次内存分配的动作,并维护一个分配对象表,当GC的时候,以全局数据区和当前寄存器中的对象为根节点,按照引用关系进行遍历,对于遍历到的每一个对象,将其标记为活的(alive)。如上图所示,假设A是处于全局

6、数据区的一个对象,那么在GC的时候将作为根节点进行遍历,由于B、C、D对象都可以由A遍历到,因此被标记为活的,E、F对象则没有被标记。注意,由于引用关系是单向的,A引用了B并不代表B也引用了A,所以遍历也只能单向进行。由于GC以全局数据区和当前寄存器中的对象为根节点进行遍历,所以对象的被标记意味着该对象可以通过全局对象或者当前上下文访问到,而没有被标记的对象则意味着该对象无法通过任何途径访问到,即该对象“失联”了,GC最终会将所有“失联”的对象内存进行回收,上图中的E和F将会在GC过程中被回收。既然mono已经有

7、了完善的GC机制,那是否还会存在内存泄漏呢?答案是肯定的,只是此处的内存泄漏需要重新定义一下,我们把对象已经不再需要使用却没有被GC回收的情况称为mono内存泄漏。Mono内存泄漏会使空闲内存减少,GC频繁,mono堆不断扩充,最终导致游戏内存占用的升高。下图就是一个mono内存泄漏的例子。解决办法对于mono内存泄漏,一般只能通过猜测+不断修改代码测试的方法来修复问题,效率很低,腾讯Wetest平台的Cube工具提供了mono内存快照对比的功能,并包括对象分配堆栈,对象引用关系等详细信息,是定位mono内存泄漏

8、问题的一大利器。下面结合具体的代码尝试使用Cube定位mono内存泄漏问题。首先我们定义类A,并在A的构造函数中申请了一块int[1000]大小的内存。接着我们定义A类型的静态变量objectA,在游戏界面上绘制一个按钮,并在按钮点击事件中给objectA赋值,此时新生成了newint[1000]对象,并由objectA引用。使用Cube的mono内存检测功能,并在按钮按

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。