亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

深入C#字符串和享元(Flyweight)模式的使用分析

2020-01-24 03:19:31
字體:
來源:轉載
供稿:網友

寫這個文章,主要是因為網上對C#字符串和享元模式的誤解比較多。

Flyweight模式
先說這名字,fly呢,就是蒼蠅,沒錯這里面不是飛的意思,是蒼蠅的意思,weight大家都知道,就是重量,蒼蠅的重量,就是非常非常輕的意思。所以Flyweight模式就是處理非常非常輕量級對象的一個東西。
Flyweight的目標是解決大量細粒度對象的內存消耗問題,當然,巧婦難為無米之炊,任何模式和手法都不能憑空造出內存來,所以享元模式針對的情況是這些細粒度對象的中數據有重復的情況。
Flyweight的做法是,把對象的狀態(通常用屬性表示),分成兩個部分,一部分是內部狀態,另一部分是外部狀態。內部狀態外部狀態是不易重復的(或者說必要的),外部狀態 內部狀態是易重復的。所以,Flyweight把外部狀態提取出來共享,這樣就一定程度解決了內存占用問題。

C#中的字符串不是Flyweight模式
在網上常??梢钥吹揭粋€說法,說C#中的字符串使用了Flyweight模式,開門見山地說,這個說法是錯誤的。
錯在哪里呢?按照上文的介紹,錯就錯在字符串它沒有所謂的“內部狀態外部狀態”。
通常講字符串是享元的原因就是以下代碼:
string a = "Hello World";
Console.WriteLine(Object.ReferenceEquals(a, "Hello World")); //True
當使用字符串直接量的時候,不論你寫了多少個"Hello World",最終內存里面只有一個字符串對象。
運行時創建的字符串并不在此列,可以使些手段,強制在內存里面產生新的字符串。
string a = "Hello World";
Console.WriteLine(Object.ReferenceEquals(a, new String("Hello World".ToCharArray())));  //False
因為我們強行調用了new,所以這個字符串跟內存中的直接量"Hello World"對應的對象不是同一個。
有趣的是,C#還允許強制把一個字符串加入到(如果已經有了,就只是找出來)字符串池里面。
string a = "Hello World";
string b = String.Intern(new String("Hello World".ToCharArray()));
Console.WriteLine(Object.ReferenceEquals(a,b) );   
或者
string a = String.Intern(new String("Hello World".ToCharArray()));
string b = String.Intern(new String("Hello World".ToCharArray()));
Console.WriteLine(Object.ReferenceEquals(a,b) );
前面提到了,這個行為跟Flyweight使用的內部狀態和外部狀態不同,是兩個對象實實在在就是同一個對象。

C#中的字符串與Flyweight模式
好吧,前面說了不少,C#中的字符串不是Flyweight模式,但是是不是就意味著C#里面字符串跟Flyweight沒有關系呢?
當然不是,否則我寫這么一篇文章豈不是太蛋疼了……
字符串池和Intern方法簡直是實現Flyweight的神器啊!
考慮我們有某一類對象,可能會創建幾百萬個,對象里面恰巧有這么一個屬性叫做顏色,它在對象構造的時候隨機產生,顏色用的是rgb色,用rgb24來表示,于是顏色字符串類似#ccc這樣子。
代碼寫起來就像下面的樣子:

復制代碼 代碼如下:

    class Element
    {
 static Random rnd = new Random();
 static char[] table;
 static Element()
 {
     table = "0123456789abcdef".ToCharArray();
 }
 public string color;
 public Element()
 {
     color = "" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16];
 }
    }

接下來我們創建3千萬個對象看看如何
復制代碼 代碼如下:

     Element[] eles = new Element[30000000];
     for (var i = 0; i < 30000000; i++)
     {
  eles[i] = new Element();
     }

從任務管理器看到一大塊內存被吃掉了

QFOMR9}(NR%(T3`V3Q35MSY

接下來我們使用String.Intern來實現Flyweight:

復制代碼 代碼如下:

    class Element
    {
 static Random rnd = new Random();
 static char[] table;
 static Element()
 {
     table = "0123456789abcdef".ToCharArray();
 }

 public string color;
 public Element()
 {
     color = String.Intern("" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16]);
 }
    }


可以看到內存占用量的明顯變化。
因為字符串對象的不可更改性質,使用了String.Intern之后,我們完全看不出前后color的區別,也就是說,修改前后的Element類是完全等效的,但是Flyweight為我們節約了大量的內存。

更多思考
這個典型的使用flyweight場景為我們揭示了享元外部狀態內部狀態的特征:像字符串一樣不可更改的對象。GoF原書的例子中的字型對象Glyph也是如此。
String.Intern這種對象池的方式實現flyweight也值得借鑒,我們可以考慮自己設計flyweight的外部狀態對象時使用類似的方式。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性理论片在线观看片免费| 亚洲精品电影网在线观看| 91av网站在线播放| 成人国产精品久久久久久亚洲| 国产欧美精品一区二区| 亚洲图片欧美日产| 色偷偷88888欧美精品久久久| www国产亚洲精品久久网站| 欧美日韩黄色大片| 97成人超碰免| 最近2019中文字幕大全第二页| 精品国产网站地址| 81精品国产乱码久久久久久| 狠狠躁夜夜躁久久躁别揉| 国产精品免费久久久久久| 大胆人体色综合| 欧美激情性做爰免费视频| 91精品国产91久久| 亚洲欧洲黄色网| 欧美精品一二区| 国产精品久久久久久超碰| 中文字幕精品在线视频| 日韩精品免费一线在线观看| 国产日韩精品在线播放| 日韩激情在线视频| 精品久久久香蕉免费精品视频| 国产精品久久激情| 国产精品久久久久久久久借妻| 国产在线拍偷自揄拍精品| 日本在线观看天堂男亚洲| 国产午夜精品免费一区二区三区| 北条麻妃在线一区二区| 国产日产欧美精品| 日韩在线视频导航| 8090理伦午夜在线电影| 91影院在线免费观看视频| 国模吧一区二区三区| 国模叶桐国产精品一区| 国产精品美女免费| 欧美国产视频一区二区| 中文字幕亚洲一区在线观看| 色偷偷88888欧美精品久久久| 欧美国产精品人人做人人爱| 亚洲国产高清高潮精品美女| 亚洲成年网站在线观看| 国产精品免费在线免费| 国产精品影片在线观看| 这里只有精品丝袜| 欧美日韩精品在线观看| 欧美亚洲成人xxx| 日本精品久久中文字幕佐佐木| 成人免费观看a| 亚洲人成在线观看网站高清| 欧美床上激情在线观看| 国产精品第七十二页| 亚洲精品乱码久久久久久按摩观| 国产日韩在线精品av| 亚洲91精品在线| 亚洲国产精品久久久久久| 欧美精品免费看| 国产精品亚洲一区二区三区| 国产女精品视频网站免费| 九九热最新视频//这里只有精品| 欧美精品www| 国产精品99久久99久久久二8| 国产精品va在线| 国产成人精品视频在线观看| 91久久精品国产91久久性色| 精品国产鲁一鲁一区二区张丽| 国产91在线播放九色快色| 欧美激情亚洲视频| 亚洲韩国欧洲国产日产av| 亚洲性夜色噜噜噜7777| 97在线观看免费| 日韩精品视频在线播放| 日韩欧美高清在线视频| 91成人天堂久久成人| 91精品国产沙发| 视频直播国产精品| 97热在线精品视频在线观看| 日韩av手机在线观看| 亚洲精品一区二区网址| 成人羞羞国产免费| 亚洲天堂av在线免费| 美女视频黄免费的亚洲男人天堂| 久久精品一本久久99精品| 亚洲精品日韩久久久| 久久久久久久久久久网站| 91久久久久久久久久| 黑人巨大精品欧美一区免费视频| 欧美色播在线播放| 亚洲成人av在线播放| 91久久精品国产91久久| 欧美黑人国产人伦爽爽爽| 精品国产福利在线| 永久免费毛片在线播放不卡| 成人免费看黄网站| www.精品av.com| 亚洲第一页自拍| 久久亚洲春色中文字幕| 88xx成人精品| 另类色图亚洲色图| 岛国av一区二区在线在线观看| 久久99热精品这里久久精品| 欧美大片第1页| 懂色av中文一区二区三区天美| 亚洲一区二区中文字幕| 亚洲精品98久久久久久中文字幕| 亚洲成人999| 中文字幕亚洲欧美一区二区三区| 亚洲国产成人久久综合一区| 亚洲福利小视频| 成人激情在线观看| 国产精品久久久久一区二区| 亚洲免费福利视频| 亚洲乱码一区av黑人高潮| 国产一区二区三区在线| 国产精品成人v| 在线观看久久久久久| 亚洲成人精品视频在线观看| 一区二区国产精品视频| 综合136福利视频在线| 91精品久久久久久久久中文字幕| 国产日韩欧美日韩| 成人h视频在线观看播放| 国产极品jizzhd欧美| 日韩免费观看视频| 日韩av毛片网| 亚洲视频一区二区| 亚洲欧美日韩天堂一区二区| 欧美老肥婆性猛交视频| 日本午夜在线亚洲.国产| 欧美性极品xxxx做受| 久久97久久97精品免视看| 亚洲aa在线观看| 岛国视频午夜一区免费在线观看| 九九精品在线观看| 久久这里有精品视频| 久久久久久久久久久国产| 国产不卡一区二区在线播放| 久久影院在线观看| 欧美性猛交xxxxx免费看| 欧美黑人又粗大| 自拍偷拍亚洲一区| 中文字幕在线精品| 亚洲综合小说区| 日韩精品在线视频| 正在播放欧美一区| 一个色综合导航| 欧美猛交ⅹxxx乱大交视频| 亚洲图片在线综合| 欧美美最猛性xxxxxx| 亚洲欧洲在线看| 国内精品伊人久久| 国语自产精品视频在线看抢先版图片| 亚洲人成网站在线播| 久久精品国产综合| 亚洲成人国产精品| 国产精品黄页免费高清在线观看| 日韩一区av在线| 国产成人精品久久二区二区91| 国产欧美日韩综合精品| 欧美日韩xxx| 久久视频这里只有精品|