2015-11-23 2 views
1

Если у меня есть это:строковый литерал и память представление

string str = "string"; 

мы можем сказать, что в куче создается объект типа string , который содержит "string"?

или

делают CLR, благодаря интернирования, создает что буквальная в стажер пула, который ссылается внутри str объекта?

так, в основном, это, образно, правильно:

str --> [ methods, fields, ..., "string"] 

или это правильно?

str --> [ methods, fields, ..., ---> "string"] 

где [ ] представляет объект.

+0

Наверняка вы можете предоставить некоторые доказательства ваших исследований ... –

+2

это зависит. значение '' string "', скорее всего, в сегменте данных, поскольку оно является константой, а не в куче –

+0

Возможно, он не знал, где искать ... Ради сохранения этого вопроса и сайта ответа. Дайте ему посмотреть [здесь] (http://csharpindepth.com/Articles/General/Strings.aspx) – Dbuggy

ответ

3

То, что вы на самом деле, кажется, спрашиваю

является интернированы строка хранится в качестве члена класса строки?

Я не нашел окончательный источник, чтобы подтвердить это, но я почти уверен, что интернированные строки поддерживаются CLR вне сферы памяти класса строки. Это указывает source for String.Intern, который взывает к способу на Thread класса:

public static String Intern(String str) { 
    if (str==null) { 
     throw new ArgumentNullException("str"); 
    } 
    return Thread.GetDomain().GetOrInternString(str); 
} 

Если интернирование влияет на объем памяти в string класса, я бы ожидать, что функция Intern для вызова методов внутри класса string вместо того, чтобы звонить в Thread.

Однако это деталь реализации (поскольку она не является частью ECMA-335 standard, которую я могу найти) и может отличаться между различными реализациями спецификации.

+0

В соответствии с [документацией по String.Intern] (https://msdn.microsoft.com/en-us/library/system.string.intern (v = vs.110) .aspx), внутренний пул представляет собой таблицу ссылки на объекты 'String' и, следовательно, будут находиться вне области памяти самого класса' String'. – DrewJordan

2

В соответствии с msdn:

общеязыковой среде выполнения автоматически поддерживает таблицу, называется стажер бассейн, который содержит единственный экземпляр каждого уникального символьной строки постоянной заявленной в программе, а также любые уникальный экземпляр String, который вы добавляете программно, вызывая метод Intern .

Струны не создаются в куче, как обычные предметы, чтобы доказать, что - если вы создаете две строки с одинаковым значением, как

string str = "string"; 
string anotherStr = "string"; 

вызова Object.ReferenceEquals(str, anotherStr) возвращается true.

Вы также можете проверить, если строка в строке бассейн с String.IsInterned

+0

строка является ссылочным типом a согласно стандартным ссылочным типам C# - это куча на основе ... – xdevel2000

+0

@ xdevel2000 - проверьте этот вопрос: http://stackoverflow.com/questions/636932/in-c-why-is-string-a-reference-type-that-behaves-like-a-value-type –

+0

Я проверяю вопрос, и принятый ответ сказал: «" Строки не являются типами значений так как они могут быть огромными и должны храниться на куче »« – xdevel2000

1

Согласно this fantastic answer, которые могли бы сделать этот вопрос дубликат, то string объект, который вы создаете всегда в куче, независимо от того или нет интернированы. Когда вы ставите строку, таблица (или внутренний пул, которая сама находится на LOH) создает новую ссылку на тот же объект (в куче), который вы уже создали ранее. Вы можете видеть the documentation for String.Intern, в котором также явно указано, что при создании объекта String используется память в куче, независимо от того, интернировано или нет.

Interning не является чем-то волшебным, чтобы поместить память в строки в другом месте, подумайте об этом как таблицу поиска для уже существующих строк, чтобы сохранить память, когда строка такая же, как и другая.