和我一起作Tess的windbg lab – Lab3, Memory

來源:互聯網
上載者:User

原文地址:http://blogs.msdn.com/b/tess/archive/2008/02/15/net-debugging-demos-lab-3-memory.aspx

操作步驟:

1、產生壓力:tinyget -srv:localhost -uri:/BuggyBits/Links.aspx -loop:4000

2、觀察taskmgr的輸出,w3wp的記憶體每秒鐘大概增長100M。

3、記憶體到700M左右的時候,抓一個hang dump

4、由於這是一個memory的問題,所以我們要先看GC Heap的情況,運行命令:!eeheap -gc,結果如下:

  GC Heap Size  0x2b307720(724596512)

  由於dump一共870M,而GC佔用了720M左右,所以我們的重點在於託管記憶體的分析。

5、看heap的整體狀況,運行!dumpheap -stat,結果如下:

  790fd8c4    49787    721599752 System.String

  嗯,720M的託管記憶體中,String佔用了絕大多數。

6、看一下string的情況,根據2/8原則,大小相同的string也許會很多,這裡我們過濾一下,看看10K以上大小的字串,運行命令:!dumpheap -mt 790fd8c4  -min 10000

  0331d6dc 790fd8c4    20020    
  03322534 790fd8c4    20020    
  0332738c 790fd8c4    20020    
  0332c1e4 790fd8c4    20020    
  0333103c 790fd8c4    20020    

  大部分都是20K的字串,隨便找一個,我們需要看它被誰分配的

7、運行!gcroot 0331d6dc,結果如下:

  Scan Thread 16 OSTHread 318
  Scan Thread 18 OSTHread c38
  Scan Thread 19 OSTHread a40
  Scan Thread 20 OSTHread c00
  Scan Thread 24 OSTHread 998
  Scan Thread 14 OSTHread 4cc
  Finalizer queue:Root:0331d6b8(Link)->
  0331d6c8(System.Text.StringBuilder)->
  0331d6dc(System.String)

  在14號線程中,Link引用了這個字串。而且我們看到,link是在Finalizer Queue中的。

8、查看finalizequeue,輸出如下:

  057e0bcc    35998       575968 Link

  一共35998個Link對象。由於該對象存在於Finalizequeue中,所以一定顯示的實現了Finalize方法。

9、查看該方法,代碼如下:

  ~Link()
  {
        //some long running operation when cleaning up the data
        Thread.Sleep(5000);
  }

10、換個方向,看上面步驟7中的那個Link對象,!do 0331d6b8,輸出結果如下:

        MT    Field   Offset                 Type VT     Attr    Value Name
  790fdc5c  4000006        4 ...ext.StringBuilder  0 instance 0331d6c8 url
  790fd8c4  4000007        8        System.String  0 instance 029bb0b8 name
  再看第一個url對象,運行!do 0331d6c8 ,結果如下:

        MT    Field   Offset                 Type VT     Attr    Value Name
  791016bc  40000b1        8        System.IntPtr  1 instance    dc1d8 m_currentThread
  79102290  40000b2        c         System.Int32  1 instance 2147483647 m_MaxCapacity
  790fd8c4  40000b3        4        System.String  0 instance 0331d6dc m_StringValue

  注意最後一行的那個m_StringValue,對比一下步驟7中的!gcroot輸入。

  從這裡我們看到,Link中包含了一個StringBuilder,而StringBuilder中包含了一個20K的字串。

11、看代碼:

  public Link(string name, string url)
      {
          this.name = name;
          this.url.Append(url);
      }
  可以看到,Link對象的構造方法中,引用了字串。

12、再回頭看上面的步驟9,Link自作聰明的實現了Finalize方法,但是該方法執行的時間太長(這裡是5秒鐘),導致記憶體回收的時候,遲遲不能把該對象回收掉。因為Link引用了字串url,所以相應的字串也無法被回收。這樣記憶體就上漲的很快了。

 

Over

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.