Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET中,内部字符串是否不属于垃圾收集?_C#_String_Garbage Collection_String Interning - Fatal编程技术网

C# 在.NET中,内部字符串是否不属于垃圾收集?

C# 在.NET中,内部字符串是否不属于垃圾收集?,c#,string,garbage-collection,string-interning,C#,String,Garbage Collection,String Interning,我正在努力减少收集Gen2所需的时间。我的应用程序创建并保存了大量字符串对象,这些字符串对象在其生命周期中一直存在 减少扫描对象的数量应减少GC时间。我想知道实习生池是否被排除在垃圾收集之外。反正那里也没有什么可收集的。如果是这样,我可以实习所有这些字符串并加速GC 如果您试图减少内存总量,请 应用程序分配,请记住,插入字符串有两个 不必要的副作用首先,为插入字符串分配的内存 直到公共语言运行时,才可能释放对象 (CLR)终止。原因是CLR对 interned String对象可以在应用程序之后

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

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

如果您试图减少内存总量,请 应用程序分配,请记住,插入字符串有两个 不必要的副作用首先,为插入字符串分配的内存 直到公共语言运行时,才可能释放对象 (CLR)终止。原因是CLR对 interned String对象可以在应用程序之后保持,甚至 您的应用程序域将终止。第二,实习一根绳子,你 必须首先创建字符串。字符串对象使用的内存 即使内存最终将被分配,也必须被分配 垃圾收集

参考:


我的

我做了一个快速测试,字符串的插入似乎并不能避免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);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
对于(int i=0;i<20000000;++i)
{
字符串s=i.ToString(“X”);
实习医生;
}
GC.Collect(3,GCCollectionMode.Forced,true);
long t1=Stopwatch.GetTimestamp();
GC.Collect(3,GCCollectionMode.Forced,true);
long t2=Stopwatch.GetTimestamp();
控制台。写线((双)(t2-t1)/秒表。频率);
}
}
此基准测试在i5 3570k上返回0.23s。如果将字符串放入数组而不是插入,则返回0.26s。如果字符串是通过
(i%10).ToString()
插入和创建的,即存在少量不同的实例,则基准测试返回微秒


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

这两种副作用都很小@kaalus已经说过“它会一直存在”,额外的GC是一次性的负担。我不是在试图减少内存使用,我是在试图减少GC Gen2time@kaalus我回答中的粗体陈述表明,内部字符串不是垃圾收集的。@DanielMann我知道内存不会被释放。我要问的是,收集器是否在每次收集时都扫描内存。减少扫描对象的数量应该减少GC时间——这是需要首先验证的。需要扫描的是对字符串的引用,这是无法避免的。但是CLR知道字符串池,它可能会快一点。@HenkHolterman说得好,但请看下面我的测试。看起来,即使字符串内部不包含任何引用并且可以跳过,实习生池也不需要扫描引用。