c#:使用using關鍵字自動釋放資源未必一定就會有明顯好處

來源:互聯網
上載者:User

 

記錄這篇文章的靈感來源來自今天下班前與同事的小小爭論,我現在開發的一個項目中,有這樣一段代碼:

public string ToXML()        {            string strXml = string.Empty;            try            {                MemoryStream ms = new MemoryStream();                XmlSerializer xml = new XmlSerializer(this.GetType());                xml.Serialize(ms, this);                byte[] arr = ms.ToArray();                strXml = Encoding.UTF8.GetString(arr, 0, arr.Length);                return strXml;            }            catch            {                return "";            }        }

  同事說象MemoryStream這類資源,應該用using包起來自動釋放資源,否則會有記憶體流失問題。在using的使用上,我也同意應該使用using,但由於這類風格的代碼在原項目中非常多(有一部分曆史原因),如果一一修改,工作量太大,時間不允許。於是我就在內心評估:如果不改,現在這種代碼的風險到底有多大?

我想很多人都知道using(Resource res = new Resrouce){},其實相當於

Resource res = new Resrouce

try{}

catch{}

finally{res.Dispose();}

對比與現有代碼的區別,無非就是資源沒有調用Dispose()釋放,但是CLR有強大的GC(記憶體回收)機制,方法調用完成後,方法體中建立的託管資源如果不再被使用,也一併會被GC列為可回收對象,所以就算開發人員沒有手動調用Dispose,其實CLR也會幫我們做這件事情,只是時機可能會晚一些而已。

於是有了下面的測試:

1.先建立一個樣本用的Class

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Xml.Serialization;namespace Model{    public class SampleClass    {        public string Name { set; get; }        public string ToXMLNoUsing()        {            string strXml = string.Empty;            try            {                MemoryStream ms = new MemoryStream();                XmlSerializer xml = new XmlSerializer(this.GetType());                xml.Serialize(ms, this);                byte[] arr = ms.ToArray();                strXml = Encoding.UTF8.GetString(arr, 0, arr.Length);                return strXml;            }            catch            {                return "";            }        }        public string ToXMLWithUsing()        {            string strXml = string.Empty;            try            {                using (MemoryStream ms = new MemoryStream())                {                    XmlSerializer xml = new XmlSerializer(this.GetType());                    xml.Serialize(ms, this);                    byte[] arr = ms.ToArray();                    strXml = Encoding.UTF8.GetString(arr, 0, arr.Length);                }                return strXml;            }            catch            {                return "";            }        }    }}

  

這其中的ToXML為了測試方便,故意分成了二個版本(一個不用using,一個用using)

2.再建立一個Console程式(命名為WithUsing),寫一段測試代碼:

using System;using System.Diagnostics;using Model;namespace WithUsing{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("開始折騰-WithUsing...");            Stopwatch watch = new Stopwatch();            int max = 100000;            watch.Reset();            watch.Start();            for (int i = 0; i < max; i++)            {                SampleClass c = new SampleClass() { Name = i.ToString().PadLeft(1024, '0') };                c.ToXMLWithUsing();            }            watch.Stop();            Console.WriteLine("完成,{0}次操作共耗時:{1}毫秒,平均{2}毫秒/次!", max, watch.ElapsedMilliseconds, watch.ElapsedMilliseconds /(decimal)max);            Console.ReadKey();        }    }}

  

3.再建立一個Console程式(命名為NoUsing),寫一段測試代碼:

using System;using System.Diagnostics;using Model;namespace NoUsing{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("開始折騰-NoUsing...");            Stopwatch watch = new Stopwatch();            int max = 100000;            watch.Reset();            watch.Start();            for (int i = 0; i < max; i++)            {                SampleClass c = new SampleClass() { Name = i.ToString().PadLeft(1024, '0') };                c.ToXMLNoUsing();            }            watch.Stop();            Console.WriteLine("完成,{0}次操作共耗時:{1}毫秒,平均{2}毫秒/次!", max, watch.ElapsedMilliseconds, watch.ElapsedMilliseconds / (decimal)max);            Console.ReadKey();        }    }}

  

編譯後,同時運行這二個程式,同時利用工作管理員觀察記憶體使用量情況:

反覆多次運行比較,發現其實二者佔用的記憶體幾乎完全相同,這說明GC還是很給力的!

而且從執行時間上看,不用Using,反而更快,這也容易理解:用Using相當於每次都要調用Dispose()方法,這會帶來一些系統開銷;而不用Using,GC會在適當的時機批量回收資源,效能反而更好。(當然:這個結論不是要誤導大家不用using,對於using還是推薦使用的!我的用意在於大家對於一些具體問題要具體分析,不可純教條主義,一味迷信某些主流的觀點)

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.