Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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
.net 关于如何避免客户端应用程序中GC延迟的建议_.net_Garbage Collection - Fatal编程技术网

.net 关于如何避免客户端应用程序中GC延迟的建议

.net 关于如何避免客户端应用程序中GC延迟的建议,.net,garbage-collection,.net,Garbage Collection,让我们想象一下这个简单的测试程序: static void Main(string[] args) { var length = 30000000; var c = new List<object>(); for (int i = 0; i < length; i++) { c.Add(new object()); } var start = DateTime.Now; GC.Collect();

让我们想象一下这个简单的测试程序:

static void Main(string[] args)
{
    var length = 30000000;
    var c = new List<object>();
    for (int i = 0; i < length; i++)
    {
        c.Add(new object());
    }
    var start = DateTime.Now;
    GC.Collect();
    GC.WaitForFullGCComplete();
    Console.WriteLine("GC took " + (DateTime.Now - start).TotalMilliseconds + " ms");
    Console.ReadKey();
}
static void Main(字符串[]args)
{
变量长度=30000000;
var c=新列表();
for(int i=0;i
在我的计算机(Framework4.0,x64)上,输出约为1.4秒,而样本消耗约1GB的RAM

问题:有没有办法加快垃圾收集?有什么最佳做法吗?在客户端应用程序中~1GB的内存消耗是很大的,但仍然相当合理。但在我的情况下,延迟超过1秒是不可接受的

只是一些可能不会得到支持但可以帮助我的想法:

  • 我可以告诉GC忽略一些对象吗
  • 为了让GC在堆的各个部分上运行,我可以将堆拆分为多个部分吗。(我更喜欢10倍100毫秒的延迟。)

您的测试完全是人为的-实际上,您不会在应用程序中显式地等待GC完成


但是,如果您有某些时间关键的代码部分,那么您可以

您的测试完全是人为的-实际上,您不会在应用程序中显式地等待GC完成


但是,如果您有某些时间关键的代码部分,那么您可以

在某些情况下,当处理大量数据时,这些数据将在相当长的时间内无法收集,那么GC可能会很烦人-会有很多引用,甚至更糟:GC实际上不太可能收集大量数据,因此浪费了时间!这里有一个选项可以考虑使用数组类型的值类型。这里的意义在于,200万个值类型的数组只是一个引用;200万的价值对收集没有任何影响。但是,子引用仍然会产生影响,例如每行
string
s。但是它

既然我提到了
string
s,那么另一个需要考虑的问题是,是否有相同基本字符组合的多个实例;例如,通过从数据库或文件加载数据。您可以考虑在那里应用一些手动字符串交互(<强> < <强> >使用<代码> String。这将再次减少用于收集的
字符串的数量


作为最后的考虑;如果您的数据需要集合,这可能会很棘手—例如,列表通常包含两个额外的对象:列表和基础数组。再乘以几百万,事情就会变得棘手起来。在我们的例子中,我们通过使用固定缓冲区解决了这一问题,但这是一个高级主题,仅当列表中的项目数量具有可预测的小“上限”时才适用。

在某些情况下,当处理大量数据时,这些数据将在相当长的时间内无法收集,然后GC可能会很烦人——会有很多引用,甚至更糟:GC实际上不太可能收集到很多引用,所以时间被浪费了!这里有一个选项可以考虑使用数组类型的值类型。这里的意义在于,200万个值类型的数组只是一个引用;200万的价值对收集没有任何影响。但是,子引用仍然会产生影响,例如每行
string
s。但是它

既然我提到了
string
s,那么另一个需要考虑的问题是,是否有相同基本字符组合的多个实例;例如,通过从数据库或文件加载数据。您可以考虑在那里应用一些手动字符串交互(<强> < <强> >使用<代码> String。这将再次减少用于收集的
字符串的数量


作为最后的考虑;如果您的数据需要集合,这可能会很棘手—例如,列表通常包含两个额外的对象:列表和基础数组。再乘以几百万,事情就会变得棘手起来。在我们的例子中,我们通过使用固定缓冲区解决了这个问题,但这是一个有点高级的主题,只有当列表中的项目数量有一个可预测的小“上限”时才适用。

如果仍然有对该列表中所有3000万个对象的引用,GC如何收集任何内容???此外,该列表可能会在LOH中结束,因此您从一开始就非常糟糕。@leppie,即使该列表最终在LOH中结束:如果该列表是引用列表,则常规堆中仍有所有对象。另外:GC没有实际收集任何东西的问题可能是这个问题中最烦人的部分:因为它没有收集任何东西,随着GC的触发,您可能会看到一系列规则的尖峰,并且没有做任何有用的事情。@MarcGravel:假设您
null
列表,列表仍然保留在LOH中。那么,实际引用是否符合GC条件?或者列表仍然会挂在它们上面吗?在列出的代码中,GC不应该收集任何东西。在我当前的项目中,有许多对象必须在GC中生存下来,这是对这种情况的一种彻底的解释。@leppie是的,内容的引用是合格的。列表本身可能由于LOH而延迟了GC,但这并不意味着列表中的任何内容都会延迟,因为最终除了引用本身之外,列表中没有任何内容。如果列表没有根目录,那么:列表没有根目录如果您仍然有对该列表中所有3000万对象的引用,GC如何收集任何内容???此外,该列表可能会以LOH结尾,因此您从一开始就非常糟糕。@leppie,即使该列表最终以o结尾