.NET中的垃圾回收是否排除了实习生字符串?

kaa*_*lus 4 c# string garbage-collection string-interning

我正在尝试减少进行Gen2收集所需的时间。我的应用程序创建并保存了大量的字符串对象,这些字符串对象一直存在。

减少扫描对象的数量应减少GC时间。我想知道实习生池是否不包括在垃圾回收中。无论如何,那里没有什么可收集的。如果是这样,我可以实习所有这些字符串并加快GC的速度。

kaa*_*lus 5

我进行了快速测试,字符串的内部保留似乎无法将它们保存起来,以免被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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

因此,可悲的是,这不是绕过垃圾收集的方法。我认为C#应该采用某种方式将字符串标记为持久性,并停止运行时浪费时间扫描它们。