Does .NET create a string intern pool for each assembly?
Asked Answered
C

1

13

I have a situation where I will encounter lots of duplicate strings which will persist in memory for a long time. I want to use String.Intern but I don't want to invade any potential application resources since my project is a library. How does this work?

Chamade answered 24/10, 2014 at 9:2 Comment(2)
Meh, interned strings are reference-counted. The primary object that holds a reference is a table (similar to HashSet) that's owned by an AppDomain. Unloading the appdomain empties the table, decrementing the reference count. The vast majority, if not all, strings should disappear. There is no "invasion" danger.Manzanilla
A bit off topic but while searching various informations about string interning I've found this very interessant blog article : blog.benoitblanchon.fr/modify-intern-pool . See also associated source code.Quarrel
B
15

The intern table for strings is CLR-scoped:

First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. The reason is that the CLR's reference to the interned String object can persist after your application, or even your application domain, terminates.

So not only the intern table is not assembly-specific, but it can outlive your assembly. The good news is that duplicated strings won't be a problem since same literal strings exist with the same reference once interned. So Interning is recommended:

The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.

string s1 = "MyTest"; 
string s2 = new StringBuilder().Append("My").Append("Test").ToString(); 
string s3 = String.Intern(s2); 
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.
Billen answered 24/10, 2014 at 9:5 Comment(1)
okay.. but in this case, these two strings should be a single reference: typeof(int).Name and "Int32" declared as variable. why they are not?Upheaval

© 2022 - 2024 — McMap. All rights reserved.