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

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

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

      查看w3wp進(jìn)程占用的內(nèi)存及.NET內(nèi)存泄露,死鎖分析

      一 基礎(chǔ)知識(shí)

       在分析之前,先上一張圖:

      從上面可以看到,這個(gè)w3wp進(jìn)程占用了376M內(nèi)存,啟動(dòng)了54個(gè)線程。

      在使用windbg查看之前,看到的進(jìn)程含有 *32 字樣,意思是在64位機(jī)器上已32位方式運(yùn)行w3wp進(jìn)程。這個(gè)可以通過(guò)查看IIS Application Pool 的高級(jí)選項(xiàng)進(jìn)行設(shè)置:

      好了,接下打開Windbg看看這個(gè)w3wp進(jìn)程占用了376M內(nèi)存,啟動(dòng)的54個(gè)線程。

      1. 加載 WinDbg SOS 擴(kuò)展命令

      .load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

      2. !dumpheap -stat

      !DumpHeap 將遍歷 GC 堆對(duì)對(duì)象進(jìn)行分析。

        MT            Count    TotalSize       Class Name
      78eb9834        1           12       System.ServiceModel.ServiceHostingEnvironment+HostingManager+ExtensionHelper

      0118c800      101        14824      Free
      ...
      63ce0004    19841      1111096 System.Reflection.RuntimeMethodInfo
      63ce2ee4    11080      2061036 System.Int32[]
      63ce0d48    34628      2242596 System.String
      63ce37b8    20012      3264884 System.Byte[]
      63cb4518   157645      4940676 System.Object[]
      Total 524310 objects

      可以看到,w3wp上總共有524310個(gè)對(duì)象, 共占用了這些內(nèi)存。

      我們可以將上述上述列出的這些對(duì)象歸為2類:

      1). 有根對(duì)象(在應(yīng)用程序中對(duì)這些對(duì)象存在引用)

      2). 自從上次垃圾回收之后新創(chuàng)建或無(wú)跟對(duì)象

      要注意的是Free這項(xiàng):

      0118c800      101        14824      Free

      這項(xiàng)一般都是GC not yet Compacted的空間或一些堆上分配的禁止GC compacted釘扣對(duì)象.

      第一欄 : 類型的方法列表 MT(method type for the type)

      第二欄:堆上的對(duì)象數(shù)量

      第三欄:所有同類對(duì)象的總大小

       

      3. !dumpheap -mt 63ce0d48   

      查看 63ce0d48  單元的有哪些對(duì)象。

      4. !do 103b3360

      看看103b3360地址的string包含哪些內(nèi)容

      可見(jiàn),103b3360地址的字符串value="System.Web.UI.PageRequestManager:AsyncPostBackError", 占120bytes. 這個(gè)字符串對(duì)象包含3個(gè)字段,它們的偏移量分別是4,8,12。

      5. dd 103b3360

      看看103b3360的值

      從左往右第一列是地址,而第二列開始則是地址上的數(shù)據(jù)。

      6. !dumpheap -type String -min 100

      看看堆上所有大于100字節(jié)的字符串。 注意:假如 -min 85000(大于85000字節(jié)的字符串或?qū)ο髮⒋鎯?chǔ)在大對(duì)象堆上). 

       

      二. NET內(nèi)存泄露分析案例

      1 基礎(chǔ)認(rèn)識(shí)

        .net世界里,GC是負(fù)責(zé)垃圾回收的,但GC僅僅是回收哪些不可及的對(duì)象(無(wú)根對(duì)象),對(duì)于有應(yīng)用的有根對(duì)象,GC對(duì)此無(wú)能為力。

        .net一些內(nèi)存泄漏的根本原因:

      • 使用靜態(tài)引用
      • 未退訂的事件-作者認(rèn)為這是最常見(jiàn)的內(nèi)存泄漏原因
      • 未退訂的靜態(tài)事件
      • 未調(diào)用Dispose方法
      • 使用不徹底的Dispose方法
      • 在Windows Forms中對(duì)BindingSource的誤用
      • 未在WorkItem/CAB上調(diào)用Remove

      一些避免內(nèi)存泄漏的建議:

      • 對(duì)象的創(chuàng)建者或擁有者負(fù)責(zé)銷毀對(duì)象,而不是使用者
      • 當(dāng)不再需要一個(gè)事件訂閱者時(shí)退訂此事件,為確保安全可以在Dispose方法中退訂
      • 當(dāng)對(duì)象不再觸發(fā)事件時(shí),應(yīng)該將對(duì)象設(shè)為null來(lái)移除所有的事件訂閱者
      • 當(dāng)模型和視圖引用同一個(gè)對(duì)象時(shí),推薦給視圖傳遞一個(gè)此對(duì)象的克隆,以防止無(wú)法追蹤誰(shuí)在使用哪個(gè)對(duì)象
      • 對(duì)系統(tǒng)資源的訪問(wèn)應(yīng)該包裝在using塊中,這將在代碼執(zhí)行后強(qiáng)制執(zhí)行Dispose

      對(duì)這些做基本了解后,我們將步入正題。

      2. 案例分析

      先上測(cè)試代碼: 

       1 public class LeakTest
       2     {
       3         private static string leakString;
       4 
       5         public LeakTest()
       6         {
       7             for (int i = 0; i < 1000; i++)
       8             {
       9                 leakString += "LEAK";
      10             }
      11         }
      12 
      13         public string GetRamdonString()
      14         {
      15             System.Random random = new System.Random();
      16 
      17             string str = string.Empty;
      18             for (int i = 0; i < 25; i++)
      19             {
      20                 str += str + random.Next(100);
      21             }
      22             return str;
      23         }
      24 
      25         public void NoDispose()
      26         {
      27             string str = GetRamdonString();
      28             
      29             ZipFile zip = new ZipFile();
      30             zip.AddEntry("a.txt", str);
      31             zip.AddEntry("b.txt", str);
      32             zip.Save("test.rar");
      33             //zip.Dispose();
      34         }
      35     }
      36 
      37     class Program
      38     {
      39         static void Main(string[] args)
      40         {
      41             LeakTest leakTest = new LeakTest();
      42             leakTest.NoDispose();
      43             Console.ReadLine();
      44         }
      45     }
      View Code

       

      需要說(shuō)明的是:

      這里程序里面定義了一個(gè)Static 字符串,及使用了Ionic.Zip 這個(gè)Zip壓縮包,僅僅是為了模擬內(nèi)存堆積現(xiàn)象,沒(méi)有調(diào)用zip.Dispose()方法,事實(shí)上Ionic.Zip并不會(huì)造成內(nèi)存泄露。

       

      正式開始了:

      啊哈,好極了。 運(yùn)行程序,好家伙,果然很耗費(fèi)內(nèi)存! 這么個(gè)小程序,吃了287M,并啟動(dòng)了12個(gè)線程.

       

       

      0:005> .load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll 
      0:005> .load C:\Symbols\sosex_64\sosex.dll

      0:005> !dumpheap -stat

       

       1 0:012> !dumpheap -stat
       2 PDB symbol for mscorwks.dll not loaded
       3 total 12840 objects
       4 Statistics:
       5               MT    Count    TotalSize Class Name
       6 000007ff001d2248        1           24 System.Collections.Generic.Dictionary`2+ValueCollection[[System.String, mscorlib],[Ionic.Zip.ZipEntry, Ionic.Zip.Reduced]]
       7 000007ff000534f0        1           24 ZipTest.LeakTest
       8 000007fee951e8e8        1           24 System.IO.TextReader+NullTextReader
       9 000007fee94f8198        1           24 System.Security.Cryptography.RNGCryptoServiceProvider
      
      11 ...
      43 000007ff001d9130 1041 66624 Ionic.Zlib.DeflateManager+CompressFunc 44 000007fee94d2d40 1023 73656 System.Threading.ExecutionContext 45 000007fee951e038 3075 1387592 System.UInt32[] 46 000007fee951ca10 3179 2450704 System.Int16[] 47 0000000000207800 261 67034512 Free 48 000007fee94d7d90 514 134251544 System.String 49 000007fee94dfdd0 102 138593344 System.Byte[] 50 Total 12840 objects

       

       

      果然,我們看到了里面有2類大對(duì)象,分別占用了134M和138M . 好家伙!

      0:005> !dumpheap -mt 

       

        1 0:012> !dumpheap -mt 000007fee94dfdd0      
        2          Address               MT     Size
        3...   
       24 00000000026f11f0 000007fee94dfdd0    65560     
       25 0000000002701288 000007fee94dfdd0    65560     
       26 00000000027112a0 000007fee94dfdd0    65592     
       27 0000000002722b50 000007fee94dfdd0    65560     
       28 0000000002752b98 000007fee94dfdd0    65560     
       29 ...    
       47 000000000290ab98 000007fee94dfdd0    65560     
       48 000000000293abe0 000007fee94dfdd0    65560     
       49 ...     
       64 0000000002ac1378 000007fee94dfdd0    65560     
       65 0000000002ad1410 000007fee94dfdd0    65560     
       66...  
      103 00000000165a71e0 000007fee94dfdd0 67108888     
      104 0000000027c11000 000007fee94dfdd0 67108888     
      105 total 102 objects
      106 Statistics:
      107               MT    Count    TotalSize Class Name
      108 000007fee94dfdd0      102    138593344 System.Byte[]
      109 Total 102 objects


      果然,有那么多65592和65560啊 啊

      隨便找一個(gè)看一下:

      0:005> !do 0000000002ba4790

      1 0:012> !do 0000000002ba4790 
      2 Name: System.Byte[]
      3 MethodTable: 000007fee94dfdd0
      4 EEClass: 000007fee90e26b0
      5 Size: 65590(0x10036) bytes
      6 Array: Rank 1, Number of elements 65566, Type Byte
      7 Element Type: System.Byte
      8 Fields:
      9 None

       

      哦。這是個(gè)一維的數(shù)組,有65566字節(jié),推測(cè)應(yīng)該好像是short(int16)長(zhǎng)度。

      繼續(xù),

      !gcroot 0000000002b42dd0

      0:012> !gcroot 0000000002b42dd0 
      Note: Roots found on stacks may be false positives. Run "!help gcroot" for
      more info.
      Scan Thread 0 OSTHread 1d3c
      RSP:18ef58:Root:00000000025c5b88(Ionic.Zip.ZipFile)->
      00000000025d2578(Ionic.Zlib.ParallelDeflateOutputStream)->
      00000000025dc528(System.Collections.Generic.List`1[[Ionic.Zlib.WorkItem, Ionic.Zip.Reduced]])->
      000000000294ac38(System.Object[])->
      0000000002b32d78(Ionic.Zlib.WorkItem)->
      0000000002b42dd0(System.Byte[])
      ...
      Scan Thread 10 OSTHread 3718

       

      這里有點(diǎn)看頭了! 看其跟對(duì)象 Ionic.Zip.ZipFile 這個(gè)對(duì)象占著沒(méi)銷毀的內(nèi)存呢!

       RSP:18ef58:Root:00000000025c5b88(Ionic.Zip.ZipFile)->
      00000000025d2578(Ionic.Zlib.ParallelDeflateOutputStream)->
      00000000025dc528(System.Collections.Generic.List`1[[Ionic.Zlib.WorkItem, Ionic.Zip.Reduced]])->
      000000000294ac38(System.Object[])->
      0000000002b32d78(Ionic.Zlib.WorkItem)->
      0000000002b42dd0(System.Byte[])

      換一個(gè)看看:

      0:012> !gcroot 00000000029bc730 
      Note: Roots found on stacks may be false positives. Run "!help gcroot" for
      more info.
      Scan Thread 0 OSTHread 1d3c
      RSP:18ef58:Root:00000000025c5b88(Ionic.Zip.ZipFile)->
      00000000025d2578(Ionic.Zlib.ParallelDeflateOutputStream)->
      00000000025dc528(System.Collections.Generic.List`1[[Ionic.Zlib.WorkItem, Ionic.Zip.Reduced]])->
      000000000294ac38(System.Object[])->
      00000000029ac6d8(Ionic.Zlib.WorkItem)->
      00000000029bc730(System.Byte[])
      ...
      Scan Thread 10 OSTHread 3718

       

      查看下其代齡:

      0:012> !gcgen 00000000029bc730
      GEN 1

      看到了,這個(gè)byte[]在1代。

       

      到此為止,還記得有個(gè)靜態(tài)字符串吧

      private static string leakString;

      我們回頭再去看看,

       !dumpheap -type String -min 1000

      0:012> !dumpheap -type String -min 1000
               Address               MT     Size
      00000000025c26e0 000007fee94d7d90     8032     
      00000000025cca30 000007fee94d7d90     1176     
      00000000025cd308 000007fee94d7d90     1600     
      000000001ae81000 000007fee94d7d90 134215704     
      total 4 objects
      Statistics:
                    MT    Count    TotalSize Class Name
      000007fee94d7d90        4    134226512 System.String
      Total 4 objects

      Next,

      0:012> !do 00000000025c26e0

      0:012> !do 00000000025c26e0 
      Name: System.String
      MethodTable: 000007fee94d7d90
      EEClass: 000007fee90de560
      Size: 8026(0x1f5a) bytes
       (C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
      String: LEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKL....
      EAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAK Fields: MT Field Offset Type VT Attr Value Name 000007fee94df000
      4000096 8 System.Int32 1 instance 4001 m_arrayLength 000007fee94df000 4000097 c System.Int32 1 instance 4000 m_stringLength 000007fee94d97d8 4000098 10 System.Char 1 instance 4c m_firstChar 000007fee94d7d90 4000099 20 System.String 0 shared static Empty >> Domain:Value 000000000062b1d0:00000000025c1308 << 000007fee94d9688 400009a 28 System.Char[] 0 shared static WhitespaceChars >> Domain:Value 000000000062b1d0:00000000025c1a90 <<

       再看下這個(gè)對(duì)象:

      !dumpobj 00000000025c26e0

      0:012> !dumpobj 00000000025c26e0 
      Name: System.String
      MethodTable: 000007fee94d7d90
      EEClass: 000007fee90de560
      Size: 8026(0x1f5a) bytes
       (C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
      (C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
      String: LEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKL....
      EAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAKLEAK Fields:
      MT Field Offset Type VT Attr Value Name 000007fee94df000 4000096 8 System.Int32 1 instance 4001 m_arrayLength 000007fee94df000 4000097 c System.Int32 1 instance 4000 m_stringLength 000007fee94d97d8 4000098 10 System.Char 1 instance 4c m_firstChar 000007fee94d7d90 4000099 20 System.String 0 shared static Empty >> Domain:Value 000000000062b1d0:00000000025c1308 << 000007fee94d9688 400009a 28 System.Char[] 0 shared static WhitespaceChars >> Domain:Value 000000000062b1d0:00000000025c1a90 <<

       

      顯示結(jié)果一樣,String:LEAKLEAKLEAKLEAKLEAK......,字符串長(zhǎng)度4000,和我們的測(cè)試代碼吻合:

      1  public LeakTest()
      2         {
      3             for (int i = 0; i < 1000; i++)
      4             {
      5                 leakString += "LEAK";
      6             }
      7         }

       

      到此,內(nèi)存查看分析演示的差不多了!

      這里我們演示的是個(gè)小得不能再小的程序,且存在前提預(yù)期。 假如在實(shí)際項(xiàng)目環(huán)境中,因?yàn)橐玫腄LL多,生成的對(duì)象繁雜,實(shí)際診斷問(wèn)題根源就復(fù)雜得多,這就需要比較扎實(shí)的基本功。

       

      . 死鎖排查

       1. 基礎(chǔ)

      還是用上面的Console App例子,運(yùn)行這個(gè)程序,啟動(dòng)了13個(gè)線程。我們先看一下這13個(gè)線程:

      !runaway

      0:012> !runaway
       User Mode Time
        Thread       Time
         0:5588      0 days 0:00:05.085
         7:4954      0 days 0:00:01.903
         3:4ddc      0 days 0:00:01.825
         8:5af4      0 days 0:00:01.809
         9:4740      0 days 0:00:01.747
        10:6c38      0 days 0:00:01.731
         4:6a94      0 days 0:00:01.700
         5:43ec      0 days 0:00:01.622
         6:8fdc      0 days 0:00:01.606
        12:1e64      0 days 0:00:00.000
        11:6a4       0 days 0:00:00.000
         2:64b4      0 days 0:00:00.000
         1:69e4      0 days 0:00:00.000

      恩。13個(gè)線程,沒(méi)錯(cuò)。 這里還可以看到每個(gè)線程的執(zhí)行時(shí)間。 其中 0 線程占用時(shí)間最多。我們?nèi)タ聪露褩U{(diào)用:

      ~0s

      !ClrStack -a

      0:012> ~0s
      ntdll!ZwRequestWaitReplyPort+0xa:
      00000000`77b714da c3              ret
      0:000> !ClrStack -a
      OS Thread Id: 0x5588 (0)
      *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v2.0.50727_64\mscorlib\c3beeeb6432f004b419859ea007087f1\mscorlib.ni.dll
      Child-SP         RetAddr          Call Site
      00000000001de670 000007fee9b02c79 DomainNeutralILStubClass.IL_STUB(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
          PARAMETERS:
              <no data>
              <no data>
              <no data>
              <no data>
              <no data>
      
      00000000001de790 000007fee9b02d92 System.IO.__ConsoleStream.ReadFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte[], Int32, Int32, Int32, Int32 ByRef)
          PARAMETERS:
              hFile = <no data>
              bytes = <no data>
              offset = <no data>
              count = <no data>
              mustBeZero = <no data>
              errorCode = 0x00000000001de820
          LOCALS:
              <no data>
              0x00000000001de7c0 = 0x0000000000000000
              <no data>
              <no data>
      
      00000000001de7f0 000007fee93f08da System.IO.__ConsoleStream.Read(Byte[], Int32, Int32)
          PARAMETERS:
              this = <no data>
              buffer = <no data>
              offset = <no data>
              count = <no data>
          LOCALS:
              0x00000000001de820 = 0x0000000000000000
              <no data>
      
      00000000001de850 000007fee9412a8a System.IO.StreamReader.ReadBuffer()
          PARAMETERS:
              this = <no data>
          LOCALS:
              <no data>
      
      00000000001de8a0 000007fee9b0622f System.IO.StreamReader.ReadLine()
          PARAMETERS:
              this = <no data>
          LOCALS:
              <no data>
              <no data>
              <no data>
              <no data>
      
      00000000001de8f0 000007ff00190188 System.IO.TextReader+SyncTextReader.ReadLine()
          PARAMETERS:
              this = 0x00000000030387b0
      
      00000000001de950 000007feea23c6a2 ZipTest.Program.Main(System.String[])
          PARAMETERS:
              args = 0x00000000027e2680
          LOCALS:
              0x00000000001de970 = 0x00000000027e26a0
      View Code

      瞧準(zhǔn)了,這是個(gè)主線程,他在等待Console.ReadLine(). 所以占用了這么長(zhǎng)時(shí)間。

       

      再在看一下這13個(gè)線程里,哪些是托管堆線程:

      !threads

      0:012> !threads
      ThreadCount: 10
      UnstartedThread: 0
      BackgroundThread: 9
      PendingThread: 0
      DeadThread: 0
      Hosted Runtime: no
                                                    PreEmptive                                                Lock
             ID OSID        ThreadOBJ     State   GC     GC Alloc Context                  Domain           Count APT Exception
         0    1 5588 00000000009d4510      a020 Enabled  00000000030387d0:000000000303a510 00000000009cb1d0     1 MTA
         2    2 64b4 00000000009dc4d0      b220 Enabled  0000000000000000:0000000000000000 00000000009cb1d0     0 MTA (Finalizer)
         3    3 4ddc 0000000000a1a010   180b220 Enabled  0000000002fe1e28:0000000002fe2450 00000000009cb1d0     0 MTA (Threadpool Worker)
         4    4 6a94 0000000000a1d590   180b220 Enabled  0000000002fe73c8:0000000002fe8450 00000000009cb1d0     0 MTA (Threadpool Worker)
         5    5 43ec 0000000000a7bbd0   180b220 Enabled  0000000002fec968:0000000002fee450 00000000009cb1d0     0 MTA (Threadpool Worker)
         6    6 8fdc 0000000000a892b0   180b220 Enabled  0000000002ff0968:0000000002ff2450 00000000009cb1d0     0 MTA (Threadpool Worker)
         7    7 4954 0000000000aa3270   180b220 Enabled  0000000002fee968:0000000002ff0450 00000000009cb1d0     0 MTA (Threadpool Worker)
         8    8 5af4 0000000000a97eb0   180b220 Enabled  0000000002fe8968:0000000002fea450 00000000009cb1d0     0 MTA (Threadpool Worker)
         9    9 4740 0000000000a99400   180b220 Enabled  0000000002fe0358:0000000002fe0450 00000000009cb1d0     0 MTA (Threadpool Worker)
        10    a 6c38 0000000000a9f3a0   180b220 Enabled  0000000002fe3e28:0000000002fe4450 00000000009cb1d0     0 MTA (Threadpool Worker)

      在托管堆上啟動(dòng)的線程有10個(gè)。這10個(gè)線程分別是什么,繼續(xù)看:

      0號(hào)MTA: 程序主線程

      MTA (Finalizer):這個(gè)是Finalizer線程,該線程負(fù)責(zé)垃圾對(duì)象回收。

      MTA (Threadpool Worker):這些是ThreadPool創(chuàng)建的線程,這里是Ionic.Zlib.WorkItem產(chǎn)生的工作線程。

      另外,CLR根據(jù)需要還會(huì)開啟其他一些線程,如:

      并發(fā)的GC線程 ,服務(wù)器GC線程 ,調(diào)試器幫助線程 ,AppDomain卸載線程 等.

       

      看一下同步塊情況,有么有死鎖?

      !syncblk

      !dlk

      0:003> !dlk
      Examining SyncBlocks...
      Scanning for ReaderWriterLock instances...
      Scanning for holders of ReaderWriterLock locks...
      Scanning for ReaderWriterLockSlim instances...
      Scanning for holders of ReaderWriterLockSlim locks...
      Examining CriticalSections...
      No deadlocks detected.

      顯示該程序沒(méi)有鎖相關(guān)資源,實(shí)際確實(shí)沒(méi)有。

       

      2 死鎖

      Lock:lock 關(guān)鍵字將語(yǔ)句塊標(biāo)記為臨界區(qū),方法是獲取給定對(duì)象的互斥鎖,執(zhí)行語(yǔ)句,然后釋放該鎖。 下面的示例包含一個(gè) lock 語(yǔ)句。

      lock 關(guān)鍵字可確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不會(huì)進(jìn)入該臨界區(qū)。 如果其他線程嘗試進(jìn)入鎖定的代碼,則它將一直等待(即被阻止),直到該對(duì)象被釋放。

       

      通常,應(yīng)避免鎖定 public 類型,否則實(shí)例將超出代碼的控制范圍。 常見(jiàn)的結(jié)構(gòu) lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 違反此準(zhǔn)則:

      • 如果實(shí)例可以被公共訪問(wèn),將出現(xiàn) lock (this) 問(wèn)題。

      • 如果 MyType 可以被公共訪問(wèn),將出現(xiàn) lock (typeof (MyType)) 問(wèn)題。

      • 由于進(jìn)程中使用同一字符串的任何其他代碼都將共享同一個(gè)鎖,所以出現(xiàn) lock("myLock") 問(wèn)題。

      最佳做法是定義 private 對(duì)象來(lái)鎖定, 或 private static 對(duì)象變量來(lái)保護(hù)所有實(shí)例所共有的數(shù)據(jù)。

       

      3 案例分析

      這個(gè)案例很簡(jiǎn)單,上菜:

       1   public class Consumer1
       2     {
       3         private string connString;
       4         public Consumer1(string str)
       5         {
       6             this.connString = str;
       7         } 
       8     }
       9 
      10     public class Consumer2
      11     {
      12         private string connString;
      13         public Consumer2(string str)
      14         {
      15             this.connString = str;
      16         }
      17     }
      18 
      19     class Program
      20     {
      21         private static Consumer1 consumer1;
      22         private static Consumer2 consumer2;
      23 
      24         static void Main(string[] args)
      25         {
      26             consumer1 = new Consumer1("Conn1");
      27             consumer2 = new Consumer2("Conn2");
      28 
      29             Thread thread = new Thread(Proc);
      30             thread.Start();
      31              
      32             lock (consumer2)
      33             {
      34                 Console.WriteLine("Proc->Lock consumer2");
      35                 Thread.Sleep(1000);
      36                 lock (consumer1)
      37                 {
      38                     Console.WriteLine("Proc->Lock consumer2->Lock consumer1 ");
      39                 }
      40             }
      41 
      42         }
      43 
      44         private static void Proc()
      45         {
      46             lock (consumer1)
      47             {
      48                 Console.WriteLine("Proc->Lock consumer1");
      49                 Thread.Sleep(1000);
      50                 lock (consumer2)
      51                 {
      52                     Console.WriteLine("Proc->Lock consumer1->Lock consumer2 ");
      53                 }
      54             }
      55 
      56         }
      57     }
      View Code

      運(yùn)行程序,便進(jìn)入死鎖。

      ok,上 windbg.

      .load C:\Symbols\sosex_64\sosex.dll

      0:000> !dlk

       

       1 0:000> !dlk
       2 Examining SyncBlocks...
       3 Scanning for ReaderWriterLock instances...
       4 Scanning for holders of ReaderWriterLock locks...
       5 Scanning for ReaderWriterLockSlim instances...
       6 Scanning for holders of ReaderWriterLockSlim locks...
       7 Examining CriticalSections...
       8 Scanning for threads waiting on SyncBlocks...
       9 *** WARNING: Unable to verify checksum for D:\Test\PInvoke\CPP\Test\bin\Debug\Test.exe
      10 Scanning for threads waiting on ReaderWriterLock locks...
      11 Scanning for threads waiting on ReaderWriterLocksSlim locks...
      12 Scanning for threads waiting on CriticalSections...
      13 *DEADLOCK DETECTED*
      14 CLR thread 0x3 holds the lock on SyncBlock 0000000000c94690 OBJ:00000000027736b8[Test.Consumer1]
      15 ...and is waiting for the lock on SyncBlock 0000000000c946d8 OBJ:00000000027736d0[Test.Consumer2]
      16 CLR thread 0x1 holds the lock on SyncBlock 0000000000c946d8 OBJ:00000000027736d0[Test.Consumer2]
      17 ...and is waiting for the lock on SyncBlock 0000000000c94690 OBJ:00000000027736b8[Test.Consumer1]
      18 CLR Thread 0x3 is waiting at Test.Program.Proc()(+0x31 IL,+0x98 Native) [D:\Test\PInvoke\CPP\Test\Program.cs @ 60,17]
      19 CLR Thread 0x1 is waiting at Test.Program.Main(System.String[])(+0x68 IL,+0x196 Native) [D:\Test\PInvoke\CPP\Test\Program.cs @ 46,17]
      20 
      21 
      22 1 deadlock detected.

      只需敲一個(gè)命令,死鎖就檢測(cè)到了。 注意下面這些地址:

      0000000000c94690 OBJ:00000000027736b8
      0000000000c946d8 OBJ:00000000027736d0
      0000000000c946d8 OBJ:00000000027736d0
      0000000000c94690 OBJ:00000000027736b8

      !mdt 00000000027736b8 看下,把這四個(gè)地址都看下:
       1 0:000> !mdt 00000000027736b8
       2 00000000027736b8 (Test.Consumer1)
       3     connString:00000000027735b8 (System.String) Length=5, String="Conn1"
       4 0:000> !mdt 00000000027736d0
       5 00000000027736d0 (Test.Consumer2)
       6     connString:00000000027735e0 (System.String) Length=5, String="Conn2"
       7 0:000> !mdt 00000000027736d0
       8 00000000027736d0 (Test.Consumer2)
       9     connString:00000000027735e0 (System.String) Length=5, String="Conn2"
      10 0:000> !mdt 00000000027736b8
      11 00000000027736b8 (Test.Consumer1)
      12     connString:00000000027735b8 (System.String) Length=5, String="Conn1"
      明了了。
      對(duì)比下上面那個(gè)程序,瞧一瞧,是不是這幾個(gè)對(duì)像,連對(duì)象里的字符串值都一覽無(wú)余!


       
       
      posted @ 2014-12-30 18:56  起點(diǎn)2014  閱讀(13088)  評(píng)論(30)    收藏  舉報(bào)
      主站蜘蛛池模板: 午夜在线不卡| 欧美熟妇乱子伦XX视频| 精品国产污污免费网站| 少妇人妻偷人精品无码视频| 国产熟女av一区二区三区| 啦啦啦高清在线观看视频www| 国产超高清麻豆精品传媒麻豆精品| 无码日韩精品一区二区三区免费| 亚洲中文字幕在线二页| 92国产精品午夜福利免费| 人妻18毛片A级毛片免费看| 日韩有码中文字幕av| 日韩成人无码影院| 欧美亚洲精品中文字幕乱码 | 久久99精品国产麻豆婷婷| 成在线人永久免费视频播放| 亚洲天堂男人影院| 国产精品白丝久久AV网站| 亚洲码和欧洲码一二三四| 乐昌市| 荣昌县| 午夜av高清在线观看| 国产精品毛片av999999| 国产99视频精品免视看9| 宿松县| 日韩乱码人妻无码中文字幕视频| 粉嫩jk制服美女啪啪| 久久精品蜜芽亚洲国产AV| 亚洲av激情五月性综合| AV最新高清无码专区| 午夜在线观看成人av| 国产精品自在自线视频| 亚洲精品国偷拍自产在线观看蜜臀| 欧美国产成人久久精品| 在线观看中文字幕国产码| 国产成人理论在线视频观看| 鸡东县| 福利在线视频一区二区| 成人自拍小视频在线观看| 99国产精品欧美一区二区三区| 亚洲av永久无码精品天堂久久|