今天一朋友跑來問我,都說C#記憶體回收多麼強大,它到底運行了嗎?記憶體回收到底是不是真的釋放著記憶體?
說真的,我被這話也問得一愣,C#代碼是寫過不少,別管是生搬硬套還是其他方法,記憶體回收的映象都是處於一個書面認識上。我從來沒測試過記憶體回收到底是個什麼狀態,也就是說從未關心過這點。實現IDisposable介面之後,按照兩種機制相配合的方式將代碼實現了,就未曾注意過軟體使用過程中記憶體的佔用情況。記憶體回收到底幹了沒有,我沒親自觀看過。
被朋友這樣一問,我便寫了一個最簡單的代碼,親自測試了一下,並親眼觀看了程式整個的運行過程,記錄了其記憶體的使用方式。
代碼如下:
1 using System;
2 using System.Collections.Generic;
3
4 namespace zuo_TestCompareProject{
5
6 #region "程式入口"
7 public class Program{
8 static void Main(){
9 Console.WriteLine("填充資料");
10 string str = Console.ReadLine();
11 List<People> lst = new List<People>();
12 for(int i=0;i<100000;i++){
13 lst.Add(new People(String.Format("{0:000000}",i)));
14 }
15 Console.WriteLine("釋放?");
16 str = Console.ReadLine();
17 foreach(People a in lst){
18 //Console.WriteLine(a); //我沒讓它顯示,挺占記憶體的說
19 a.Dispose();
20 }
21 str = Console.ReadLine();
22 }
23 }
24 #endregion
25
26 #region "垃圾收集實驗類"
27 //定義一個存放人類資訊的人類
28 //實現IDisposable介面
29 public class People:IDisposable
30 {
31 private string pname;
32
33 public People(string n){
34 this.pname = n;
35 }
36
37 public override string ToString()
38 {
39 return String.Format("姓名:{0}",this.pname);
40 }
41
42 bool isPosed = false; //釋放控制開關
43 public void Dispose(){ //實現介面中的方法
44 Dispose(true);
45 System.GC.SuppressFinalize(this); //手工釋放過的,就不要再調用解構函式進行釋放了
46 }
47
48 public virtual void Dispose(bool disposeing){ //方法重載
49 if(!isPosed){ //如果未調用過,則進入釋放資源
50
51 if(disposeing){ //手工釋放
52 //釋放所有託管資源
53 //Console.WriteLine("釋放所有託管資源。"); //我沒讓它顯示,挺占記憶體的說
54 System.GC.Collect(); //強制進行記憶體回收
55 }
56
57 //釋放未託管的資源,如資料庫連接、檔案關閉等操作
58 //Console.WriteLine("釋放未託管的資源,如資料庫連接、檔案關閉等操作..."); //我沒讓它顯示,挺占記憶體的說
59 }
60
61 isPosed = true; //已經釋放過資源了
62 }
63
64 ~People(){
65 Dispose(false); //程式員未進行手工釋放,由記憶體回收自動進行
66 }
67 }
68 #endregion
69 }
建立了一個自訂的People類,在其內部實現了IDisposable介面
在Main()裡面,一次性產生了10萬個引用對象,此時被分配到了‘堆’上。
然後開始執行逐個對象釋放過程。
觀看並記錄其運行情況如下:
程式一開啟,處於初始化狀態,此時佔用的記憶體是:7140k
當我按下任意鍵,開始填充資料,整個資料填充完畢後,此時佔用的記憶體是:14544k
開始逐個對象的調用其Dispose()方法,整個過程一開始,佔用記憶體是:17856k
釋放過程在繼續,因為建立的引用對象不少,變動過一次資料,佔用記憶體是:17884k
繼續釋放,過了沒一會,時間不長,資料再次變動,佔用記憶體是:14524k----------------------------從此時,看到了垃圾是工作了,釋放記憶體了。
繼續釋放,這次過了好久,資料再次發生變動,佔用記憶體是:6652k--------------------------------可以看到記憶體釋放的很明顯。
至此一直到釋放完畢,一直保持著,記憶體佔用量:6652k----------------------------------大約持續了總時間的三分之一左右。
程式終結,退出。
不知道朋友們對這個‘記憶體回收’是否還有其他方面的認識?可否跟貼交流一下,我也跟著長長見識。先在此感謝各位跟貼的朋友。