匿名函数gc分析
测试一:使用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:
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的值,为什么呢?来分析一波:
可以看匿名函数所访问的外部变量都会在临时类里面创建一个拷贝,这样每个类对象的大小就不一样了。
附上类型定义的完整代码,前因后果一目了然:
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分析的更多相关文章
- Javascript闭包和C#匿名函数对比分析
C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...
- python——内置函数和匿名函数
内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...
- Python_匿名函数_47
匿名函数 Eva_J 匿名函数:为了解决那些功能很简单的需求而设计的一句话函数 #这段代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc ...
- python----内置函数2与匿名函数
1.迭代器生成器相关 range:创建一个可迭代对象,一般与for混合使用,可设置步长. for i in range(0,10,2): #步长2范围为0-10不包括10 print(i) # 0 2 ...
- python全栈开发之匿名函数和递归函数
python 匿名函数和递归函数 python全栈开发,匿名函数,递归函数 匿名函数 lambda函数也叫匿名函数,即函数没有具体的名称.是为了解决一些功能很简单需求而设计的一句话函数.如下: #这段 ...
- python——内置函数和lambda匿名函数
内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...
- Python— 匿名函数
匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的 “一句话函数” #初始代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = ...
- python之路——内置函数和匿名函数
阅读目录 楔子 内置函数 匿名函数 本章小结 楔子 在讲新知识之前,我们先来复习复习函数的基础知识. 问:函数怎么调用? 函数名() 如果你们这么说...那你们就对了!好了记住这个事儿别给忘记了,咱们 ...
- python 内置函数和匿名函数
内置函数 截止到python版本3.6.2,现在python一共为我们提供了68个内置函数. Built-in Functions abs() dict() help() min() ...
随机推荐
- 机器学习系列-tensorflow-02-基本操作运算
tensorflow常数操作 import tensorflow as tf # 定义两个常数,a和b a = tf.constant(2) b = tf.constant(3) # 执行默认图运算 ...
- JavaScript基础笔记(七)DOM
DOM DOM可以将任何HTML或者XML文档描述成一个由多层节点构成的结构. 一.节点层次 一)Node类型 DOM1定义了一个Node接口,该接口将由DOM中所有节点类型实现. 每一个节点都有一个 ...
- Android应用的内存管理
管理应用的内存可以分为两个部分内容: 1. 首先需要理解:How Android Manages App Processes and Memory Allocation? 2. 其次需要考虑:我们设计 ...
- SpringMVC框架简介
1.简介 SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 01.Spring mvc的优缺点 M ...
- .net异常机制
异常机制简介 当CPU运行到一些非法的指令,例如除零错误,访问内存页失败等指令,CPU会生成一个硬件异常,不同的异常有固定的异常代码作为标识符,异常产生以后CPU暂时不能继续执行后续的指令—因为后续的 ...
- ssm框架出现的常见问题
1:自己写的代码测试的时候显示用户过期,需要释放拦截器,并配置权限允许 2:Servlet.service() for servlet [springmvc] in context with path ...
- Git_git diff 与 git diff -- cached 区别
1.首先,打开一个干净的工作区 2.对文件进行修改 3.使用 git diff 进行查看(这里的解释可能不是很准确,暂时这么理解!) 4. 执行 git add 将工作区中的内容add到stage, ...
- uploadify Cookie 验证登入上传问题
上传文件时必须验证是否已登入. 当用FormsAuthentication做登入,使用FormsAuthentication.FormsCookieName进行验证是否已登入即可. <scrip ...
- mvn -N和-U的用法
mvn参数-N.-U理解 关于-N -N,--non-recursive Do not recurse into sub-projects 意思是,不递归到子项目(子模块). 举例: 一个父项目下Fa ...
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春
中国大学MOOC-陈越.何钦铭-数据结构-2017春 学习地址 详细学习内容 Github记录地址 欢迎fork和star,有惊喜值得学习! 参考学习笔记 参考AC代码 数据结构和算法学习笔记 学习内 ...