1

If I have this:

string str = "string";

can we say that on the heap is created an object of type string that contains "string"?

or

does the CLR, thanks to interning, creates that literal into an intern pool that's referenced inside str object?

so, basically, is this, figuratively, correct:

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

or is this correct?

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

where [ ] represents the object.

Hazem Abdullah
  • 1,837
  • 4
  • 23
  • 41
xdevel2000
  • 20,780
  • 41
  • 129
  • 196
  • Surely you can provide some evidence of your research... – rory.ap Nov 23 '15 at 14:03
  • 2
    it depends. the value `"string"` is likely in the data segment as it a constant and not in the heap – Daniel A. White Nov 23 '15 at 14:05
  • Perhaps he didn't know where to look... For the sake of keeping this a question and answer site. Let him look [here](http://csharpindepth.com/Articles/General/Strings.aspx) – Dbuggy Nov 23 '15 at 14:05
  • 1
    Are you asking if the the interned string is stored as a property of the string class? I'm pretty certain that the string pool is maintained by the CLR and not embedded in the string class. However, that may be an implementation detail that is subject to change. – D Stanley Nov 23 '15 at 14:10
  • @Dbuggy, I read the article and a string is a reference type so str contains a reference to an object of type string. However I don't understand if the string literal "string" is setted inside that object (i.e. into a private variable) or not... – xdevel2000 Nov 23 '15 at 14:11
  • @DStanley, yes I'm asking that... – xdevel2000 Nov 23 '15 at 14:12
  • No string is just a reference type which acts like it's a value type. This means that the string object refers prolly using a reference or unsafe pointer (i don't care about this) to the internal pool of strings. – Dbuggy Nov 23 '15 at 14:12
  • 1
    As far as I understand, run-time strings are not interned until you call `String.Intern` method manually. So, before `Intern` calling I think the first case is correct; and after calling the second case becomes correct. – Mark Shevchenko Nov 23 '15 at 14:20
  • What's the purpose for the question? are you just curious or are you making design decisions based on the answer? – D Stanley Nov 23 '15 at 14:38
  • @DStanley, no, It is only for reasons of study – xdevel2000 Nov 23 '15 at 14:41

3 Answers3

3

What you really appear to be asking is

is the interned string stored as a member of the string class?

I haven't found a definitive source to confirm this, but I'm pretty certain that the interned strings are maintained by the CLR outside of the memory scope of the string class. This is indicated by the source for String.Intern, which calls out to a method on the Thread class:

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

If interning affected the memory footprint of the string class, I'd expect the Intern function to call methods within the string class rather than call out to Thread.

However, this is an implementation detail (since it's not part of the ECMA-335 standard that I can find) and may be different between different implementations of the spec.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • According to [the String.Intern documentation](https://msdn.microsoft.com/en-us/library/system.string.intern(v=vs.110).aspx), the intern pool is a table of references to `String` objects, and thus would be outside the memory footprint of the `String` class itself. – DrewJordan Nov 23 '15 at 14:40
  • 1
    For those diving into the rabbithole, It pretty much ends here [https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/coreclr/src/vm/stringliteralmap.cpp#L212] – VisualBean Nov 16 '20 at 10:36
2

According to msdn:

The common language runtime automatically maintains a table, called the intern pool, which contains a single instance of each unique literal string constant declared in a program, as well as any unique instance of String you add programmatically by calling the Intern method.

The strings are not created on the heap like ordinary objects, to prove that - if you create two strings with the same value, like

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

calling Object.ReferenceEquals(str, anotherStr) returns true.

You can also check if string is in the string pool with String.IsInterned

w.b
  • 11,026
  • 5
  • 30
  • 49
  • string is a reference type an according to the C# standard reference type are heap based... – xdevel2000 Nov 23 '15 at 14:30
  • @xdevel2000 - check this question: http://stackoverflow.com/questions/636932/in-c-why-is-string-a-reference-type-that-behaves-like-a-value-type – w.b Nov 23 '15 at 14:31
  • I check the question and the accepted answer said: """Strings aren't value types since they can be huge, and need to be stored on the heap""" – xdevel2000 Nov 23 '15 at 14:37
  • 1
    I think, having further researched it, that this isn't quite correct. "The strings are not created on the heap like ordinary objects..." The *first* instance of the string is (on the heap), but subsequent instances will reference the same object. – DrewJordan Nov 23 '15 at 15:00
1

According to this fantastic answer which might make this question a duplicate, the string object that you create is always on the heap, whether or not it's interned. When you intern a string, the table (or intern pool, which itself resides on the LOH) creates a new reference to the same object (on the heap) that you already created before. You can see the documentation for String.Intern which also mentions explicitly that when you create a String object, memory on the heap is used, whether or not it's interned.

Interning isn't some magic to put the memory for strings elsewhere, think of it as a lookup table for already existing strings, to save memory when a string is the same as another one.

Community
  • 1
  • 1
DrewJordan
  • 5,266
  • 1
  • 25
  • 39