c# - .NET 中的垃圾收集是否排除了驻留字符串?

标签 c# string garbage-collection string-interning

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

减少扫描对象的数量应该会减少 GC 时间。我想知道实习生池是否被排除在垃圾收集之外。反正那里也没什么可收集的。如果是这样,我可以实习所有这些字符串并加速 GC。

最佳答案

我做了一个快速测试,字符串的驻留似乎并不能避免它们被 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# 应该有一些方法来将字符串标记为持久的,并停止运行时在扫描它们时浪费时间。

关于c# - .NET 中的垃圾收集是否排除了驻留字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34779141/

相关文章:

c# - 为什么即使在强制垃圾回收时,已完成的线程使用的内存也不会被释放?

c# - 虚函数在 C# 和 Java 中如何工作?

java - Java中如何计算字符串开头某个字符出现的次数

c# - 将字符串拆分为包含在捕获括号中的数组

r - 使用 gc() 命令强制在 R 中运行垃圾回收

c# - 多次调用 SuppressFinalize

c# - 响应类、ServiceStack 中的 IEnumerable 与列表

c# - 如何将 MMMdyyyyhhmmtt 格式的日期时间字符串转换为日期时间对象?

c# - 在 try catch 中抛出自定义异常

c# - .NET 字符串性能问题