抛出异常会消耗大量内存

时间:2017-07-21 17:36:31

标签: c# .net

我正在实现一些看起来像这样的重试代码:

protected void LoadPSVToContext()
{
    var tokenizedFile = GetTokenizedValuesForFile();

    var retries = 0;
    var retryMax = 5;
    var doDataLoad = true;

    while (doDataLoad)
    {
        try
        {
            LoadData(ref tokenizedFile);
            doDataLoad = false;
        } catch (Exception e)
        {
            if (retries < retryMax)
            {
                retries++;
                _nlog.Info($"Retrying {retries}/{retryMax}");
            }
            else
            {
                _nlog.Error("Max retries exceeded.");
                throw;
            }
        }
    }

    _nlog.Info("File sent to database...");
}

public void LoadData(ref string[][] tokenizedFile)
{
    throw new Exception("Test timeout");
}

在第一次尝试'LoadData'之前,App的内存为95megs。抛出第一个异常后,应用程序爆炸到261兆!每次重试之后只会变得更糟,当我重试5时,我的应用程序是1.2 Gigs并且内存不足。我没有在循环中分配任何内存,我通过引用传递所有内容,所以这些疯狂的分配来自哪里? GC.collect()几乎没有帮助解决这个问题,因为分配发生的速度非常快,以至于GC无法在内存异常之前释放它。

帮助理解这一点将不胜感激。

更新#1

我的GetTokenizedValuesForFile代码发出了请求:

public string[][] GetTokenizedValuesForFile()
{
    var recordCount = File.ReadLines(DecryptedFilePath).Count();
    var result = new string[recordCount][];

    using (var parser = new TextFieldParser(DecryptedFilePath))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(Settings.Default.FieldSeperator);
        while (!parser.EndOfData)
        {
            //Processing row
            result[parser.LineNumber - 1] = parser.ReadFields();
        }
    }
    return result;
}

1 个答案:

答案 0 :(得分:1)

首先,我要感谢大家的意见和建议。这是我从其他人手中接过的一个项目,并且在每个人都表示不相信我所描述的内容可能会发生之后,我意识到我必须在项目中遗漏一些东西。

一个名为AspectInfo.cs的小文件让我很好奇所以我打开它并注意到一个全局的Logging方面应用于整个应用程序并捕获并记录了项目中发生的任何异常。通常我认为这将是一个巧妙的技巧,除非它捕获异常的整个上下文并且上下文恰好包含一个巨大的数据数组。

评论方面立即解决了内存问题。因此,这可能有助于将来某人短路寻找问题。