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();
}
在我的计算机上(Framework 4.0,x64),输出约为1.4秒,而样本消耗约1GB的RAM。
问题:有没有办法加速垃圾收集?任何最佳做法?客户端应用程序中大约1GB的内存消耗很多,但仍然相当合理。但在我的情况下,延迟时间> 1秒是不可接受的。
可能不会支持但可以帮助我的想法:
答案 0 :(得分:4)
在某些情况下,当处理大量无法收集的数据相当长的时间时,GC可能很烦人 - 会有很多引用,甚至更糟:GC实际上不太可能收集太多,所以浪费时间!这里的一个选项可以是考虑使用值类型的数组等。这里的意义是200万个值类型的数组只是一个引用; 200万值对收集没有任何影响。但是,子引用仍会产生影响,例如每行string
个。但它can help。
由于我提到了string
,所以另外要看的是你是否有多个相同的基础字符组合的实例;例如,通过从数据库或文件加载数据。您可以考虑在那里应用一些手动字符串实习(不使用string.Intern
- 但是每个加载字典或类似字典)。这将再次减少正在收集的string
个数。
最后的想法;如果您的数据需要集合,那可能会很棘手 - 例如,列表通常涉及额外的2个对象:列表和基础数组。乘以几百万,事情就变得棘手了。在我们的情况下,我们通过使用固定缓冲区解决了这个问题,但这是一个高级主题,并且只有在您对项目数量有可预测且小的“上限”时才适用。列表。
答案 1 :(得分:0)
您的测试完全是人为的 - 实际上,您不会明确等待GC在您的应用程序中完成。
但是,如果您有一些时间关键的代码段,那么您可以disable GC temporarily。