Dot-Net

.NET 將字元串值放在哪裡?

  • October 13, 2019

我正在使用 SOS 調試擴展 dll 來檢查 String 類型的記憶體佈局,結果如下。

!dso

ESP/REG  Object   Name

0015EFC0 01c6b9cc System.String    hello,world

!do 01c6b9cc

Name:        System.String

MethodTable: 6de3f9ac

EEClass:     6db78bb0

Size:        36(0x24) bytes

File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089>\mscorlib.dll

String:      hello,world

Fields:
     MT    Field   Offset                 Type VT     Attr    Value Name

6de42978  40000ed        4         System.Int32  1 instance       11 m_stringLength

6de41dc8  40000ee        8          System.Char  1 instance       68 m_firstChar

6de3f9ac  40000ef        8        System.String  0   shared   static Empty

   >> Domain:Value  00331488:01c61228 <<

現在我想知道,字元串值“hello world”到底儲存在哪裡?

謝謝。

在 m_firstChar。堆分配足夠大以容納整個字元串,而不僅僅是第一個字元。在 Visual Studio 中也很容易看到:

class Program {
   static void Main(string[] args) {
       string s = "hello" + "world";
   }  // <=== Breakpoint here
}

當斷點命中時,使用 Debug + Windows + Memory + Memory1。在地址框中鍵入 s。你會看到的:

0x01B3F6BC  e8 0a 67 6e 0b 00 00 00 0a 00 00 00 68 00 65 00  è.gn........h.e.
0x01B3F6CC  6c 00 6c 00 6f 00 77 00 6f 00 72 00 6c 00 64 00  l.l.o.w.o.r.l.d.
  • 對像從地址 - 4 開始,syncblk 儲存在那裡(不可見)。
  • 接下來的 4 個字節是方法表指針(0x6e670ae8,又名類型句柄)。
  • 接下來的 4 個字節是 m_arrayLength 成員,字元串的分配大小 (0x0b)。
  • 接下來的 4 個字節是 m_stringLength 成員,即字元串中的實際字元數 (0x0a)。
  • 下一個字節儲存字元串,從 m_firstChar 開始。

這適用於 .NET 3.5 SP1。您不會在 .NET 4.0 及更高版本中看到 m_arrayLength 成員,該欄位已被刪除。

引用自:https://stackoverflow.com/questions/5240971