日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# Lambda 和 匿名函数的GC总结

發布時間:2023/12/13 C# 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# Lambda 和 匿名函数的GC总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于Lambda和 匿名函數,閉包的GC,其實可以總結為兩條。

為了方便理解,以舉例說明,首先我們定義變量,靜態變量,以及函數如下:

static int staticVariable = 0;int variable = 0;private void Func(Action callback){}private void StaticFunc(Action callback){}private void Callback(){}private void Callback2(){variable++;}private static void StaticCallback(){staticVariable++;}

總結1:若是一個匿名函數引用到外部變量,則會造成一個閉包,C#為了實現這一點會生成一個匿名類(記住,類都是引用類型)來保存用到的外部變量,因此當調用這個閉包時,首先會實例化一個副本,同時會采用外部變量實際值來初始化這個副本,最終致使會在堆上分配內存。也就是說閉包就一定會產生內存分配

總結2: 在C#中全部方法的引用都是引用類型,都會被分配到堆中。把一個方法做為參數傳遞時,都會產生臨時的內存分配,無論傳遞的是匿名方法還是已經定義的方法

網上有的文章是這么寫的,但是實際上,紅色這句話應該是錯誤的,當傳遞的是已經定義的方法時,是一定會產生內存分配,當傳遞的是匿名方法時,要看該匿名方法是否是閉包

例如:

void Update(){//傳遞的是已經定義的方法,有內存分配Func(Callback);//傳遞的是已經定義的方法,雖然是靜態函數,也有內存分配Func(StaticCallback);//傳遞的匿名方法,由于是靜態函數不是閉包,無內存分配Func(() => StaticCallback());//傳遞的匿名方法,由于是靜態變量不是閉包,無內存分配Func(() =>{staticVariable++;});//傳遞的匿名方法,由于是靜態函數不是閉包,無內存分配Func(() =>{StaticCallback();});//傳遞的匿名方法,由于是普通成員函數是閉包,有內存分配Func(() => Callback());//傳遞的匿名方法,不是閉包,無內存分配Func(() =>{int i = 0;i++;});//傳遞的匿名方法,是閉包,有內存分配Func(() =>{variable++;});}

更進一步測試:

public Action test;void Update(){//是閉包,有內存分配test = () =>{variable++;};//傳遞的是函數名,有內存分配test = Callback;//傳遞的是函數名,有內存分配test = Callback2;//傳遞的是函數名,有內存分配test = StaticCallback;//傳遞的是匿名函數,不是閉包,無內存分配test = () => { };//傳遞的是匿名函數,不是閉包,無內存分配test = () => { StaticCallback(); };}

因此:

1) 盡量避免將方法作為參數傳遞,如果無法避免,優先采用匿名方法,且盡量不要產生閉包,比如可以將所需的外部變量傳入而不是直接應用

2)盡量避免使用閉包,如果無法避免,絕對不能每幀執行的函數中使用閉包

總結

以上是生活随笔為你收集整理的C# Lambda 和 匿名函数的GC总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。