<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      eaglet

      本博專注于基于微軟技術(shù)的搜索相關(guān)技術(shù)
        博客園  :: 首頁  :: 新隨筆  :: 聯(lián)系 :: 訂閱 訂閱  :: 管理

      用 .NET Memory Profiler 跟蹤.net 應(yīng)用內(nèi)存使用情況--基本應(yīng)用篇

       

      作者:肖波
            .net 框架號稱永遠(yuǎn)不會發(fā)生內(nèi)存泄漏,原因是其引入了內(nèi)存回收的機(jī)制。但實際應(yīng)用中,往往我們分配了對象但沒有釋放指向該對象的引用,導(dǎo)致對象永遠(yuǎn)無法釋放。最常見的情況就是給對象添加了事件處理函數(shù),但當(dāng)不再使用該對象時卻沒有將該函數(shù)從對象的事件handler中減掉。另外如果分配了非托管內(nèi)存,而沒有手工釋放,GC同樣無能為力。所以當(dāng).net應(yīng)用發(fā)生內(nèi)存泄漏后如何跟蹤應(yīng)用的內(nèi)存使用情況,定位到程序設(shè)計中的缺陷顯得非常重要。本文將介紹通過.NET Memory Profiler來跟蹤.net應(yīng)用的內(nèi)存泄漏,為定位.net應(yīng)用內(nèi)存問題提供一個解決途徑。

           .NET Memory Profiler是一款強(qiáng)大的.net 內(nèi)存跟蹤和優(yōu)化工具。該工具目前可以對一下4種.net應(yīng)用進(jìn)行內(nèi)存跟蹤。

      • 基本應(yīng)用 例如winform, console application等
      • ASP.net 應(yīng)用
      • WPF應(yīng)用
      • Window 服務(wù)

           本篇將通過對以下三種內(nèi)存的跟蹤來闡述如何使用該工具對基本.net應(yīng)用程序進(jìn)行內(nèi)存的跟蹤。三種內(nèi)存包括:

      • 托管內(nèi)存
      • 線程托管內(nèi)存
      • 非托管內(nèi)存

       

      在開始之前,先需要建立環(huán)境。
             我采用.NET Memory Profiler V3.1.307 版本進(jìn)行測試。安裝完后需要新建一個項目,由于我們需要測
      .net基本應(yīng)用,所以新建項目時選擇Standalone application. 點擊next后,輸入要測試的.net 應(yīng)用的路徑和參數(shù)。
      然后按下 finish.項目就建立完成了。

             測試程序是我編寫的,編譯后生成TestMemorySize.exe 這個控制臺應(yīng)用程序。下載地址

             代碼如下

       

           主程序等待用戶輸入,輸入m,t,u 分別是增加托管內(nèi)存,創(chuàng)建一個自動增加托管內(nèi)存的線程,增加非托管內(nèi)存。
      輸入d,釋放主線程創(chuàng)建的托管內(nèi)存對象。

      using System;
      using System.Collections.Generic;
      using System.Text;

      namespace TestMemorySize
      {
          
      class Program
          {
              
      static void Main(string[] args)
              {
                  MemoryInc memoryInc 
      = new MemoryInc();

                  
      while (true)
                  {
                      
      long memorysize = System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64;

                      Console.WriteLine(
      string.Format("PagedMemorySize:{0}MB", memorysize / (1024*1024)));
                      Console.WriteLine(
      string.Format("ManagedMemIncTimes:{0}", memoryInc.ManagedMemIncTimes));
                      Console.WriteLine(
      string.Format("UnmanagedMemIncTimes:{0}", memoryInc.UnmanagedMemIncTimes));

                      String cmd 
      = Console.ReadLine();

                      
      switch (cmd)
                      {
                          
      case "d":
                              memoryInc 
      = new MemoryInc();
                              GC.Collect();
                              
      break;
                          
      case "m":
                              memoryInc.IncManagedMemory();
                              
      break;
                          
      case "u":
                              memoryInc.IncUnmanagedMemory();
                              
      break;
                          
      case "t":
                              MemoryLeakThread thread 
      = new MemoryLeakThread();
                              
      break;
                          
      case "l":
                              
      break;
                      }
                  }
              }
          }
      }

       

      MemoryInc 是一個增加托管內(nèi)存和非托管內(nèi)存的類。

       

      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Runtime.InteropServices;

      namespace TestMemorySize
      {
          
      class MemoryInc
          {
              
      int _ManagedMemIncTimes = 0;
              
      int _UnmanagedMemIncTimes = 0;

              List
      <byte[]> _ManagedMemory = new List<byte[]>();
              LinkedList
      <IntPtr> _UnmanagedMemory = new LinkedList<IntPtr>();

              
      /// <summary>
              
      /// Managed memory increase times
              
      /// </summary>
              public int ManagedMemIncTimes
              {
                  
      get
                  {
                      
      return _ManagedMemIncTimes;
                  }
              }

              
      /// <summary>
              
      /// Unmanaged memory increase times
              
      /// </summary>
              public int UnmanagedMemIncTimes
              {
                  
      get
                  {
                      
      return _UnmanagedMemIncTimes;
                  }
              }

              
      /// <summary>
              
      /// Increase managed memory
              
      /// </summary>
              public void IncManagedMemory()
              {
                  _ManagedMemIncTimes
      ++;

                  _ManagedMemory.Add(
      new byte[1024 * 1024 * _ManagedMemIncTimes]);
              }

              
      /// <summary>
              
      /// Increase unmanaged memory
              
      /// </summary>
              public void IncUnmanagedMemory()
              {
                  _UnmanagedMemIncTimes
      ++;

                  _UnmanagedMemory.AddLast(Marshal.AllocCoTaskMem(
      1024 * 1024 * _UnmanagedMemIncTimes));
              }
          }
      }

       

      MemoryLeakThread 這個線程沒30秒增加1M的托管內(nèi)存占用。

       

       

      MemoryLeakThread


           準(zhǔn)備就緒,下面就開始體驗了。

      1、托管內(nèi)存的跟蹤
             菜單中選擇Profiler->Start 啟動TestMemorySize.exe,然后輸入m 并回車,這是分配了1M的托管內(nèi)存。
      在菜單中選擇Profiler->Collect Heap Shapshot. 這是就可以看到堆中的所有對象了。

       

       

      從這個界面我們看到雖然列出了對象的列表,但只有類型和大小等信息,卻沒有對象的名稱以及分配過程
      信息,這樣怎么定位那塊內(nèi)存沒有被釋放啊?不要著急,.NET Memory Profiler還是比較強(qiáng)大的,讓我們繼續(xù)往下
      前進(jìn)。

       

      雙擊選中的對象后進(jìn)入對象所占用的堆的詳細(xì)信息

       

       

      再雙擊選中行,這時我們就可以看到對象的名稱和分配堆棧的情況了。是不是很興奮?終于找到是哪個家伙在搗蛋了。

       

       

      2、線程中創(chuàng)建的托管內(nèi)存的跟蹤
             線程中創(chuàng)建的托管內(nèi)存跟蹤方法和第1節(jié)介紹的方法基本是一樣的。啟動TestMemorySize.exe后輸入t 并回車,創(chuàng)建一個
      吃內(nèi)存的線程。下面步驟都相同了。

       

       

       

      3、非托管內(nèi)存的跟蹤
             要跟蹤非托管內(nèi)存需要做一個設(shè)置:選擇菜單中view->Project Property Pages,按下圖進(jìn)行設(shè)置。

       

      設(shè)置好后啟動TestMemorySize.exe后輸入u 并回車,創(chuàng)建1M的非托管內(nèi)存。下面步驟相同。

       

       

       

       

      非托管內(nèi)存無法看到對象的名稱,但可以看到內(nèi)存的申請過程,這對于定位內(nèi)存問題已經(jīng)提供了很大的幫助。

      現(xiàn)在我們再輸入m 回車,創(chuàng)建1M的托管內(nèi)存,然后輸入d 回車,這時我們可以發(fā)現(xiàn)memoryInc對象申請的托管內(nèi)存已經(jīng)被釋放掉,
      但非托管內(nèi)存依然存在,內(nèi)存在這里泄漏了!

      這個工具還可以幫助我們計算出托管對象在堆中實際占用的內(nèi)存大小,這也是一個很實用的功能,我們可以發(fā)現(xiàn)實際的占用大小
      要比我們設(shè)計的大小略大,這是因為我們設(shè)計的類及其成員都是從一些基類中繼承,這些基類的數(shù)據(jù)占用了一些內(nèi)存造成。

       

      到此如何跟蹤基本.net應(yīng)用的內(nèi)存問題就介紹完畢。有時間再謝謝怎么跟蹤ASP.NET應(yīng)用的內(nèi)存問題。
      這一篇本來上午就要發(fā)出來,都快寫完了,IE 崩潰!抓狂!

      下午又重新寫了一遍,郁悶啊。


       

      主站蜘蛛池模板: 亚洲精品宾馆在线精品酒店| 国产中文99视频在线观看| 美女无遮挡免费视频网站| 日韩av无码精品人妻系列| 亚洲日本欧洲二区精品| 日本视频一两二两三区| 国产综合色在线精品| 国产成人一区二区三区影院动漫| h无码精品动漫在线观看| 亚洲精品一区二区天堂| 18禁黄无遮挡网站免费| 亚洲线精品一区二区三八戒| 国产男女黄视频在线观看| 猫咪社区免费资源在线观看| 滁州市| 亚洲欧美国产精品久久久久久久 | 久久精品国产99久久六动漫| 亚洲国模精品一区二区| www亚洲精品| 国产日产精品系列| 亚洲国产超清无码专区| 日韩精品亚洲国产成人av| 久久人人97超碰精品| 右玉县| 中文字幕日韩国产精品| 欧美www在线观看| 中文字幕无线码免费人妻| 亚洲av无码牛牛影视在线二区 | 亚洲AV日韩精品久久久久| 成人自拍短视频午夜福利| 日韩中文字幕亚洲精品| 精品无码专区久久久水蜜桃| 亚洲天堂一区二区成人在线| 日本亲近相奷中文字幕| 紫金县| 国产自在自线午夜精品| 精品久久久无码人妻中文字幕| 视频一区二区不中文字幕| 国产激情第一区二区三区| 成人做爰视频www| 日韩av不卡一区二区在线|