垃圾收集器不收集String.Split字符串

时间:2015-04-15 13:18:19

标签: c#

我正在尝试解析大的CSV文件。为此,我在新线程中启动我的函数,然后执行此操作:

 using (StreamReader sr = new StreamReader(CurrentFilePath, Encoding.UTF8))
 {
     while (!sr.EndOfStream)
     {
         String strLine = sr.ReadLine();
         String[] strFields = strLine.Split('\t');
         //Processing my array
      }
 }

这里没什么不寻常的。但我注意到String.Split创建的每个私有字符串都保存在内存中。因此,当我在Y列上解析带有X行的文件时,我的内存中仍然有几乎X * Y的字符串(使用.NetMemoryProfiler也表示它们尚未被GC收集)。

是因为它是在另一个线程中启动的吗?有什么想法吗?

- 编辑 - 我在这个类中存储了我的CSV的31列中的20列:

    class InputEntry {
         public String Field1 {get;set;}
         public String Field2 {get;set;}
         public String Field2 {get;set;}
         ...
    }

如果我加载216Mo文件(288000行有31列),当我将每行存储在InputEntry类的列表中时,即使平均字符串长度为37个字符,内存也需要450Mo。 / p>

1 个答案:

答案 0 :(得分:2)

这是因为.NET中的垃圾收集只是在事后才发生。垃圾收集释放内存,但它以CPU时间为代价。因此,提前收集并不总是可行的,特别是如果当时内存不是很高的话。最终,.NET决定这一点。

但是,您可以立即发出调用以立即进行垃圾收集。

GC.Collect();

但通常不鼓励这样做。

在此处查找更多信息:

GC.Collect (MSDN)

When is it acceptable to call GC.Collect?