在.NET中,实习字符串是否从垃圾收集中排除?

我正在努力减少进行Gen2收集所需的时间。 我的应用程序创建并保存了大量的字符串对象,这些对象在其生命中持续存在。

减少扫描对象的数量应减少GC时间。 我想知道实习池是否被排除在垃圾收集之外。 无论如何,没有任何东西要收集。 如果是这样,我可以实习所有这些字符串并加速GC。

如果您尝试减少应用程序分配的内存总量,请记住,实习字符串有两个不需要的副作用。 首先,在公共语言运行时(CLR)终止之前,不太可能释放为被占用的String对象分配的内存。 原因是CLR对interned String对象的引用可以在应用程序甚至应用程序域终止后持久存在。 其次,要实习字符串,必须先创建字符串。 必须仍然分配String对象使用的内存,即使内存最终将被垃圾回收。

参考: https : //msdn.microsoft.com/en-us/library/system.string.intern(v= vs.110) .aspx

强调我的。

我做了一个快速测试并且字符串的实习似乎没有将它们从GC扫描中保存下来。 至少不是在.NET 4.5 64位。

class Program { static void Main(string[] args) { for (int i = 0; i < 20000000; ++i) { string s = i.ToString("X"); string.Intern(s); } GC.Collect(3, GCCollectionMode.Forced, true); long t1 = Stopwatch.GetTimestamp(); GC.Collect(3, GCCollectionMode.Forced, true); long t2 = Stopwatch.GetTimestamp(); Console.WriteLine((double)(t2 - t1) / Stopwatch.Frequency); } } 

该基准在i5 3570k上返回0.23秒。 如果将字符串放入数组而不是实习,则返回0.26s。 如果字符串是通过(i % 10).ToString()和创建的,即存在少量不同的实例,则基准返回微秒。

很遗憾,这不是绕过垃圾收集的方法。 我认为C#应该有一些方法将字符串标记为持久性并停止运行时浪费时间扫描它们。