C#应用程序每次调用都需要更多内存

时间:2013-11-25 13:50:07

标签: c# performance memory-management memory-leaks ants

我开发了一个应用程序,它创建了一堆带有sql作为数据的pdf报告。

在此图中,您可以在使用500,100,100和500 PDF文件执行作业时查看此应用程序的已分配空间。

allocated working set

问题是,每个作业后分配的空间增加。所以在某些时候应用程序崩溃了。首先,应用程序需要73476 KB,在上一次报告后我需要230188 KB内存。

将从任务中调用此代码。

public static bool Run(string id, SessionDescription session, IProgress<ProgressState> progress = null, CancellationToken cancellationToken = new CancellationToken(), Func<string,bool> prepareTargetFolder = null)
{
    SessionDescription.Validate(session);
    var pageLibrary = CreatePageLibrary(id, session.FrxFiles.Select(f => f.FullPath), session.PageDescriptions, session.Mappings);
    session.PageDescriptions = CompletePageDescriptionDataSourceNames(session.PageDescriptions, pageLibrary);

    if (cancellationToken.IsCancellationRequested) return false;

    try
    {
        var parallelOptions = new ParallelOptions() {MaxDegreeOfParallelism = 1, CancellationToken = cancellationToken};

        long count = 0;

        if (session.Jobs.Count > 0)
        {
            var job = session.Jobs.First();
            job.TargetSpec = TargetDescription.ComposeFullPath(session.Target ?? new TargetDescription(), job.TargetSpec, job.DataSourceSet, 0);
            if (prepareTargetFolder != null && !prepareTargetFolder(Path.GetDirectoryName(job.TargetSpec)))
                return false;

            ProcessOneDocument(id, session.PageDescriptions, session.PageCompositions, pageLibrary, job.DataSourceSet, session.BackpageName, job.TargetSpec);
            ProcessProgress(progress, ref count, session.Jobs.Count, job.TargetSpec);
        }

        Parallel.For(1, session.Jobs.Count, parallelOptions, index =>
        {
            var job = session.Jobs[index];
            ProcessJob(id, index, job, session, pageLibrary);
            ProcessProgress(progress, ref count, session.Jobs.Count, job.TargetSpec);
        });
    }
    catch (OperationCanceledException)
    {
        return false;
    }
    catch (AggregateException exception)
    {
        throw exception.Flatten();
    }
    finally
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
    return true;
}

我添加了

GC.Collect();
GC.WaitForPendingFinalizers();

但我不是一个自称为GC的粉丝。它并没有帮助对抗内存使用的稳定增长。

我尝试用ANTS Memory Profiler分析已用内存。它没有管理的最常用的空间,所以我不知道你应该受到责备。

ANTS Memory Profiler

Memory Comsumption

所以任何想法?

  

更新,报告将使用fastreport .net 2013.3创建,我添加了更多代码。

很多! 马丁

1 个答案:

答案 0 :(得分:1)

这听起来像你正在使用的应用程序或库中的内存泄漏。任何实现IDisposable的东西都应该被处理或包装在一个使用块中。与某些人的看法相反,C#可能会出现内存泄漏,特别是如果您使用包装本机代码的内容。有关内存泄漏可能发生的示例,请参阅this

另外,请记住内存使用情况以及GC回收的方式因机器而异。 GC不保证在需要之前回收内存,因此虽然有时看起来像是发生了内存泄漏(尤其是在服务器操作系统上运行),但实际上并非如此。这不是这里的情况,因为你得到了OOM但是要考虑的是纯粹上升的记忆并不总是表明泄漏