测试一:使用member function创建action会产生gc,不管该函数是否访问外部变量:

    private System.Action memberAct = null;
// gc 112B
private void ActionWithMethod()
{
memberAct = new System.Action(LocalMethod);
}
// gc 112B, if LocalMethod() is static, then no gc
private void ActionWithMethod2()
{
memberAct = LocalMethod;
}
// no gc
private void ActionWithMethod3()
{
System.Action act = memberAct;
}
private void LocalMethod()
{
foreach (var item in lst)
Debug.Log(item);
}

  ActionWithMethod和ActionWithMethod2是等效的,gc值如下所示:

  

  IL代码也一摸一样:

  

  所以将一个member function复制给一个action会产生gc,解决的办法就是ActionWithMethod3,也就是用一个actin member缓存起来,然后将缓存的action member复制给新建的action,这样只会产生一次gc:

  如果将LocalMethod设置为static函数,则ActionWithMethod2也不会产生gc:
    private static void LocalMethod()
{
}

  

测试二:使用匿名函数,如果访问了外部变量,也会产生gc;如果不访问外部变量,则只产生一次gc

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestAnonymousFunctionGC : MonoBehaviour
{
private System.Action actMember = null;
private int iMember = ;
public TestAnonymousFunctionGC()
{
}
private void Update()
{
UnityEngine.Profiling.Profiler.BeginSample("*** AnoymousFunctionWithoutArg ***");
AnoymousFunctionWithoutArg();
UnityEngine.Profiling.Profiler.EndSample();
UnityEngine.Profiling.Profiler.BeginSample("*** AnoymousFunctionWithMemberArg ***");
AnoymousFunctionWithMemberArg();
UnityEngine.Profiling.Profiler.EndSample();
UnityEngine.Profiling.Profiler.BeginSample("*** AnoymousFunctionWithLocalArg1 ***");
AnoymousFunctionWithLocalArg1();
UnityEngine.Profiling.Profiler.EndSample();
UnityEngine.Profiling.Profiler.BeginSample("*** AnoymousFunctionWithLocalArg2 ***");
AnoymousFunctionWithLocalArg2();
UnityEngine.Profiling.Profiler.EndSample();
UnityEngine.Profiling.Profiler.BeginSample("*** AnoymousFunctionWithLocalArg3 ***");
AnoymousFunctionWithLocalArg3();
UnityEngine.Profiling.Profiler.EndSample();
}
// no gc
private void AnoymousFunctionWithoutArg()
{
actMember = () => { };
}
// gc 112B
private void AnoymousFunctionWithMemberArg()
{
actMember = () =>
{
Debug.Log(iMember);
};
}
// gc 129B
private void AnoymousFunctionWithLocalArg1()
{
bool bValue = true;
actMember = () =>
{
Debug.Log(bValue);
};
}
// gc 132B
private void AnoymousFunctionWithLocalArg2()
{
int iValue = ;
actMember = () =>
{
Debug.Log(iValue);
};
}
// gc 136B
private void AnoymousFunctionWithLocalArg3()
{
int iValue = ;
int iValue2 = ;
actMember = () =>
{
Debug.Log(iValue);
Debug.Log(iValue2);
};
}
}

  

  同时还可以发现,匿名函数引用的外部变量的个数会影响gc的值,为什么呢?来分析一波:

  

  可以看到访问外部变量的匿名函数,会导致临时对象的创建,这样会导致gc,那位为什么每个临时变量的gc值不一样呢,我们来看一下这些临时class的定义:

  

  可以看匿名函数所访问的外部变量都会在临时类里面创建一个拷贝,这样每个类对象的大小就不一样了。

  附上类型定义的完整代码,前因后果一目了然:

public class TestAnonymousFunctionGC : MonoBehaviour
{
// Fields
private Action actMember;
private int iMember; // Methods
public TestAnonymousFunctionGC()
{
this.actMember = null;
this.iMember = ;
base..ctor();
return;
} [CompilerGenerated]
private void <AnoymousFunctionWithMemberArg>b__5_0()
{
Debug.Log((int) this.iMember);
return;
} private void AnoymousFunctionWithLocalArg1()
{
<>c__DisplayClass6_0 class_;
class_ = new <>c__DisplayClass6_0();
class_.bValue = ;
this.actMember = new Action(class_.<AnoymousFunctionWithLocalArg1>b__0);
return;
} private void AnoymousFunctionWithLocalArg2()
{
<>c__DisplayClass7_0 class_;
class_ = new <>c__DisplayClass7_0();
class_.iValue = ;
this.actMember = new Action(class_.<AnoymousFunctionWithLocalArg2>b__0);
return;
} private void AnoymousFunctionWithLocalArg3()
{
<>c__DisplayClass8_0 class_;
class_ = new <>c__DisplayClass8_0();
class_.iValue = ;
class_.iValue2 = ;
this.actMember = new Action(class_.<AnoymousFunctionWithLocalArg3>b__0);
return;
} private void AnoymousFunctionWithMemberArg()
{
this.actMember = new Action(this.<AnoymousFunctionWithMemberArg>b__5_0);
return;
} private void AnoymousFunctionWithoutArg()
{
this.actMember = (<>c.<>9__4_0 != null) ? <>c.<>9__4_0 : (<>c.<>9__4_0 = new Action(this.<AnoymousFunctionWithoutArg>b__4_0));
return;
} private void Update()
{
Profiler.BeginSample("*** AnoymousFunctionWithoutArg ***");
this.AnoymousFunctionWithoutArg();
Profiler.EndSample();
Profiler.BeginSample("*** AnoymousFunctionWithMemberArg ***");
this.AnoymousFunctionWithMemberArg();
Profiler.EndSample();
Profiler.BeginSample("*** AnoymousFunctionWithLocalArg1 ***");
this.AnoymousFunctionWithLocalArg1();
Profiler.EndSample();
Profiler.BeginSample("*** AnoymousFunctionWithLocalArg2 ***");
this.AnoymousFunctionWithLocalArg2();
Profiler.EndSample();
Profiler.BeginSample("*** AnoymousFunctionWithLocalArg3 ***");
this.AnoymousFunctionWithLocalArg3();
Profiler.EndSample();
return;
} // Nested Types
[Serializable, CompilerGenerated]
private sealed class <>c
{
// Fields
public static readonly TestAnonymousFunctionGC.<>c <>;
public static Action <>9__4_0; // Methods
static <>c()
{
<> = new TestAnonymousFunctionGC.<>c();
return;
} public <>c()
{
base..ctor();
return;
} internal void <AnoymousFunctionWithoutArg>b__4_0()
{
return;
}
} [CompilerGenerated]
private sealed class <>c__DisplayClass6_0
{
// Fields
public bool bValue; // Methods
public <>c__DisplayClass6_0()
{
base..ctor();
return;
} internal void <AnoymousFunctionWithLocalArg1>b__0()
{
Debug.Log((bool) this.bValue);
return;
}
} [CompilerGenerated]
private sealed class <>c__DisplayClass7_0
{
// Fields
public int iValue; // Methods
public <>c__DisplayClass7_0()
{
base..ctor();
return;
} internal void <AnoymousFunctionWithLocalArg2>b__0()
{
Debug.Log((int) this.iValue);
return;
}
} [CompilerGenerated]
private sealed class <>c__DisplayClass8_0
{
// Fields
public int iValue;
public int iValue2; // Methods
public <>c__DisplayClass8_0()
{
base..ctor();
return;
} internal void <AnoymousFunctionWithLocalArg3>b__0()
{
Debug.Log((int) this.iValue);
Debug.Log((int) this.iValue2);
return;
}
}
} Collapse Methods

参考:https://blog.uwa4d.com/archives/Anonymous_heapmemory.html

Vector3.Equals函数会有gc:

        // Vector3.Equeals有GC 28B
{
UnityEngine.Profiling.Profiler.BeginSample("*** Vector3.Equals ***");
Vector3 dir1 = Vector3.one, dir2 = Vector3.one;
var equals = dir1.Equals(dir2);
UnityEngine.Profiling.Profiler.EndSample();
}

匿名函数gc分析的更多相关文章

  1. Javascript闭包和C#匿名函数对比分析

    C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...

  2. python——内置函数和匿名函数

    内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...

  3. Python_匿名函数_47

    匿名函数 Eva_J 匿名函数:为了解决那些功能很简单的需求而设计的一句话函数 #这段代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc ...

  4. python----内置函数2与匿名函数

    1.迭代器生成器相关 range:创建一个可迭代对象,一般与for混合使用,可设置步长. for i in range(0,10,2): #步长2范围为0-10不包括10 print(i) # 0 2 ...

  5. python全栈开发之匿名函数和递归函数

    python 匿名函数和递归函数 python全栈开发,匿名函数,递归函数 匿名函数 lambda函数也叫匿名函数,即函数没有具体的名称.是为了解决一些功能很简单需求而设计的一句话函数.如下: #这段 ...

  6. python——内置函数和lambda匿名函数

    内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...

  7. Python— 匿名函数

    匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的  “一句话函数” #初始代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = ...

  8. python之路——内置函数和匿名函数

    阅读目录 楔子 内置函数 匿名函数 本章小结 楔子 在讲新知识之前,我们先来复习复习函数的基础知识. 问:函数怎么调用? 函数名() 如果你们这么说...那你们就对了!好了记住这个事儿别给忘记了,咱们 ...

  9. python 内置函数和匿名函数

    内置函数 截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.     Built-in Functions     abs() dict() help() min() ...

随机推荐

  1. 2017-9-15-Linux移植:WinSCP软件 & SSH Server开启

    在Linux电脑上面安装了TFTP server,但是各种不给力,决定寻找其他办法在Windows和Linux之间传输文件. WinSCP 是一个 Windows 环境下使用 SSH 的开源图形化 S ...

  2. 英语口语练习系列-C24-杂技-问候语-乡愁

    1. 词汇-杂技 acrobatics noun [ U ] UK /ˌæk.rəˈbæt.ɪks/ US /ˌæk.rəˈbæt̬.ɪks/ the skills of an acrobat 杂技 ...

  3. (文件操作)Android相关的File文件操作

    判断文件是否存在: /** * 判断文件是否存在 * * @param path 文件路径 * @return [参数说明] * @return boolean [返回类型说明] */ public ...

  4. servlet模板的修改

    找到myeclipse的安装目录: 找到此目录下的这个jar包 右键以压缩包的方式打开然后找到templates文件夹并打开它: 在打开的templates文件夹找到并以高级记事本打开Servlet. ...

  5. 备份LeetCode OJ自己编写的代码

    常泡LC的朋友知道LC是不提供代码打包下载的,不像一般的OJ,可是我不备份代码就感觉不舒服- 其实我想说的是- 我自己写了抓取个人提交代码的小工具,放在GitCafe上了- 不知道大家有没有兴趣 ht ...

  6. PhotoshopCC 2017安装破解 + cuterman

    之前安装了PhotoshopCC 2017版本的软件,但是绿色版的(安装简介.使用方便).但是在随着Adobe公司对设计的不断追求和工具的不断更新,更加强大.更加优秀的设计插件和工具不断出新,最近朋友 ...

  7. BZOJ3070 : [Pa2011]Prime prime power 质数的质数次方

    对于$a^b$,如果$b=2$,那么在$[\sqrt{n},\sqrt{n}+k\log k]$内必定能找到$k$个质数作为$a$. 筛出$n^{\frac{1}{4}}$内的所有质数,暴力枚举所有落 ...

  8. pythonweb服务器编程(二)

    Web静态服务器-1-显示固定的页面 #coding=utf-8 import socket from multiprocessing import Process def handleClient( ...

  9. 模板-gcd

    GCD int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } EXGCD void ex_gcd(int a, int b, int & ...

  10. word2vec skip-gram系列2

    Word2Vec的CBOW模型和Skip-gram模型 故事先从NNLM模型说起,网络结构图如下图所示,接下来先具体阐述下这个网络, 输入是个one-hot representation的向量.比如你 ...