Где .NET размещает строковое значение? - PullRequest
14 голосов
/ 09 марта 2011

Я использую расширение 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"?

Спасибо.

Ответы [ 2 ]

14 голосов
/ 09 марта 2011

у 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, ручка типа aka).
  • Следующие 4 байта - это член m_arrayLength, выделенный размер строки (0x0b).
  • Следующие 4 байта являются членом m_stringLength, фактическим количеством символов в строке (0x0a).
  • Следующие байты хранят строку, начиная с m_firstChar.

Это для .NET 3.5 SP1.Вы не увидите члена m_arrayLength в .NET 4.0 и выше, поле было удалено.

3 голосов
/ 09 марта 2011

Как и строка C, она хранится в байтах m_stringLength, начинающихся с m_firstChar, что является небезопасным указателем, а не действительным символом. В C # используется строка с префиксом длины, а не строка с разделителем null.

Тем не менее, красота CLR в том, что вам не нужно заботиться. Как это стало проблемой?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...