文章出處

對于WEB程序來說,它寄宿在IIS提供的w3wp進程中,這個進程占用的內存大小和你的應用程序的使用有個直接關系,你的程序寫的標準,它占用內存就相對低,你的程序寫的偽范規,該釋放的東西不讓系統釋放(有些對象GC回收不了),就會造成內存使用過高的情況,對于32位系統來說,最高1.6G,超過后,進程自動掛掉!

對于本地服務來說,一般我們采用windowService,windowform來承載,它會自己有一個進程,而最近,我的windowService占用內存過高的問題真的出現了,不到5分鐘,進程已經達到500多兆了,而且還在處理遞增長的趨勢,當我們review代碼后,發現了一個大問題,看下面代碼您是否也發現了呢,代碼里的壞味道

   public class User_SendMessageJob : JobBase, IJob
    {
        private static object lockObj = new object();
        private object IBigRepository = new object();
        public void Execute(IJobExecutionContext context)
        {
            lock (lockObj)
            {
                #region 需要處理的任務
                //Logger.Info(context.JobDetail.Key.Name + DateTime.Now);
                #endregion
            }
        }
    }

上面的代碼,聲明了兩個全局變量lockObj和IBigRepository,其中這個IBigRepository在方法Execute被調用,并用是輪訓調用,為了避免并發沖突,采用了lock進行排它鎖的設計,當這個全局對象本應該在程序運行結束后,就被釋放,但是,我們去想,如果線程1正在執行lock里的代碼,而線程2這種由于輪訓服務,也開始進入方法,這時IBigRepository對象沒有被釋放,線程2又產生了一個新的對象,這時,我們的IBigRepository對象就越來越多,導致你的內存消耗越來越大!

正確的作法應該是,將IBigRepository對象聲明在Execute方法里,作為局部變量,當lock結束后,就會被系統自動加收,下一個線程2進來后,才會建立新的IBigRepository對象,這樣,我們就保存了,在輪訓服務中,始終只有一個IBigRepository對象被建立,這種設計才是正確的.

看一下修改后的代碼

 public class User_SendMessageJob : JobBase, IJob
   {
        private static object lockObj = new object();
        public void Execute(IJobExecutionContext context)
        {
            lock (lockObj)
            {
                object IBigRepository = new object();

                #region 需要處理的任務
                //Logger.Info(context.JobDetail.Key.Name + DateTime.Now);
                #endregion
            }
        }
   }

在修改了程序之后,再看一下內存,只有200M,而且沒有遞增的趨勢,這才是正確的程序,所以說,有些基礎知識很重要,我們不應該去忽視它,就像老趙說過一句話:學好操作系統才能寫出好的windows程序,學習IIS運行機制,才能寫出好的WEB程序!

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()