How to prevent string being interned

Before trying out to prevent the interning I would suggest to use String.IsInterned() to find out whether the strings you are concerned with are actually interned at all. If that function returns null, your string is not interned.

As far as I know strings that are generated dynamically at runtime are not interned at all, since there would be no performance benefits .


If you need to remove the strings from memory for security reasons, use SecureString.

Otherwise, if there are no references to the string anywhere, the GC will clean it up anyway (it will no longer be interned) so you don't need to worry about interning.

And of course, only string literals are interned in the first place (or if you call String.Intern() as noted above by Petr and others).


Apply CompilationRelaxations attribute to the entire assembly (looks like the only possible solution is to forbid interning on an assembly level) as follows:

[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)]

More information on CompilationRelaxations

UPDATE:

The documentation states that the attribute:

Marks an assembly as not requiring string-literal interning.

In other words, it does not prevent the compiler from doing string interning, just providing a hint that it is not required. The documentation is a little bit sparse in this area, but this also seems to be the conclusion in this MSDN forum post.

From this SO question on that attribute


You are saying to things:

  • You are processing a lot of strings, so you are talking about runtime values.
  • You want to remove the strings from memory after you are done processing them.

By default, runtime values are NOT interned. When you receive a string from a file or create a string yourself, they all have a separate instance. You can Intern them via String.Intern. Interning strings takes more time, but consumes less memory. See: http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

Runtime strings are automatically removed by the GC if there is no reference to them. An interned will have more references, but at the end of your process, I assume that all references are removed. The interning-mechanism does not keep a HARD reference, but a WEAK reference. A weak reference is ignore by the GC, so the string instance can still be removed. See: http://msdn.microsoft.com/en-us/library/system.weakreference.aspx

So... to sum it up. By default your runtime strings are not interned. And if they would be interned, they are still removed by the GC after your work is done.

Tags:

C#

Memory