C# 协程 WaitForSeconds产生GC(Garbage Collection)问题

孙广东   2015.4.9   24:00

先来看看使用协程的作用一共有两点:
    1)延时(等待)一段时间执行代码;
    2)等某个操作完成之后再执行后面的代码。总结起来就是一句话:控制代码在特定的时机执行。
协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。

对于使用协程带来GC问题,不推荐使用了!。

使用我之前封装的  游戏简单控制逻辑Clock类    可以完美解决

IEnumerator myAwesomeCoroutine()

{

    while (true)

    {

        doAwesomeStuff();

        yield return new WaitForSeconds(waitTime);

    }

}

我想要指出的是使用 "yield return new WaitForSeconds()" 将会每帧导致垃圾分配GC,21个字节,由于"new" 部分(相对于标准的协程 "yield return null"只产生 9 个字节)。

若要避免此问题,只是提前设置你的wait 等待的时间......

WaitForSeconds shortWait = new WaitForSeconds(0.1f);
WaitForSeconds longWait = new WaitForSeconds(5.0f);
IEnumerator myEvenAwesomerCoroutine()
{
    while (true)
    {
        if (iNeedToDoStuffFast)
        {
            doAwesomeStuffReallyFast();
            yield return shortWait;

        }
        else{
            dontDoMuch();
            yield return longWait;
        }
    }
}

现在你coroutine 协程每次调用只会引起最低 的9 字节 GC 分配 (不包括其他分配allocations,当然你可能通过您其他的代码会导致 !)。

防止GC而做的事情的列表可能比较长。
- 不要使用Invoke或 StartCoroutine 的字符串。

- 不要使用GUILayout 和标记您的 GUI MonoBehaviour来防止每帧 800bytes的GC发生。 http://docs.unity3d.com/ScriptReference/MonoBehaviour-useGUILayout.html

- 不要使用 GameObject.Tag 或 GameObject.Name

- 不要在Update中使用GetComponent ,如果可能的话将其缓存

- 不要使用 foreach

-  不要使用string +  ----》 StringBuild 或 string.Format()

??

时间: 2024-10-04 12:28:33

C# 协程 WaitForSeconds产生GC(Garbage Collection)问题的相关文章

深入理解Java中的Garbage Collection

前提 最近由于系统业务量比较大,从生产的GC日志(结合Pinpoint)来看,需要对部分系统进行GC调优.但是鉴于以往不是专门做这一块,但是一直都有零散的积累,这里做一个相对全面的总结.本文只针对HotSpot VM也就是Oracle Hotspot VM或者OpenJDK Hotspot VM,版本为Java8,其他VM不一定适用. 什么是GC(Garbage Collection) Garbage Collection可以翻译为"垃圾收集" -- 一般主观上会认为做法是:找到垃圾,

GC(Garbage Collection)垃圾回收机制

1.在垃圾回收器中,程序员没有执行权,只有通知它的权利. 2.程序员可以通过System.gc().通知GC运行,但是Java规范并不能保证立刻运行. 3.finalize()方法,是java提供给程序员用来释放对象或资源的办法,但是尽量少用. 一.GC的介绍 GC的全称是Garbage Collection (垃圾收集) 在GC中,垃圾所指的是程序在运行过程中,会产生出一些无用的对象,或者说是已经被弃用的对象,而这些对象会占用着一部分的内存空间,如果长时间不去回收这些内存空间,那么最终会导致O

【Unity】理解协程的原理1——实现一个自己的WaitForSeconds

协程的所能达到的效果就是在指定的时间点上执行需要执行的代码,Unity中开始一个协程的函数是StartCoroutine,而提供的延迟的类有以下几种分别是 new WaitForEndOfFrame; //等待一帧 new WaitForFixedUpdate; //等待一个FixedUpdate(固定时间间隔) new WaitForSeconds; //等待X秒 new WWW; //等待外部资源加载完毕 本文就针对其中的WaitForSeconds实现进行探究. 因为在开发过程中,很多时候

面试必问:Golang高阶-Golang协程实现原理

引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发) 进程和线程的区别 进程是计算机资源分配的最小单位,进程是对处理器资源(CPU),虚拟内存(1)的抽象, 虚拟内存是对主存资源(Memory)和文件(2)的抽象,文件是对I/O设备的抽象. 虚拟内存是操作系统初始化后内部维护的一个程序加载空间,对于32位操作系统来说,也就是寄存器有32位的比特长度,虚拟内存中每个字节都有一个内

Unity3D之协程

Unity3D提供了一个工具叫做“协程”,所谓协程就是使用StartCoroutine()里面添加一个方法来调用该方法.对这个被调用的方法有如下规定:返回值必须是IEnumerator类型.那么为什么要使用协程呢?通常这是为了应付某一类需要,比如想要延时执行某一段代码,或者使用www进行一些请求和加载等阻塞操作. 协程与多线程没有关系.协程每一帧都执行,时间段位于LateUpdate之后.所以说它只不过是在主线程里面每帧执行的一个函数而已.协程使用的原理类似于foreach循环,都是使用迭代器来

python协程的实现(greenlet源码分析)

基本上读完了greenlet的源代码,代码不多,就2000行C语言的代码,其中有一部分栈寄存器的修改的代码是由汇编实现的... 一句话来说明greenlet的实现原理:通过栈的复制切换来实现不同协程之间的切换... 那么接下里来具体的来看看greenlet的代码到底是怎么实现的... 好了,先来看看greenlet对象对应的C语言结构体: /** States: stack_stop == NULL && stack_start == NULL: did not start yet sta

Unity协程(Coroutine)原理深入剖析再续

Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine)的认识和理解,主要讲到了Unity引擎在执行协程(Coroutine)的原理(Unity协程(Coroutine)原理深入剖析)和对协程(Coroutine)状态的控制(Unity协程(Coroutine)管理类--TaskManager工具分享),到这使用Coroutine的疑问就没有了,但是D

Unity中使用协程进行服务端数据验证手段

近期在做项目中的个人中心的一些事情,用户头像上传,下载,本地缓存,二级缓存,压缩,这些都要做,麻雀虽小五脏俱全啊,也是写的浑浑噩噩的, 当我们在上传用户头像的时候,向服务端发送上传头像请求之前,一般都会做一次验证,向服务端获取token验证信息,来确保非法上传,如果不做这个那么会有非法用户上传非法图像,使你的服务器 带来未知的灾难. 而验证的逻辑很好写,并没有什么难度,比如: Server.SendMessage("获取token"); Client.Receive(string to

C#中的yield return与Unity中的Coroutine(协程)(下)

Unity中的Coroutine(协程) 估计熟悉Unity的人看过或者用过StartCoroutine() 假设我们在场景中有一个UGUI组件, Image: 将以下代码绑定到Image 1 using UnityEngine; 2 using System.Collections; 3 using System.Threading; 4 using UnityEngine.UI; 5 6 public class CoroutineDemo : MonoBehaviour { 7 8 //