有关垃圾回收C#.NET的问题

gur*_*kan 5 c# garbage-collection

我的应用程序遇到OutOfMemoryException问题。我的应用程序可以在文本中搜索单词。当我开始长时间运行的过程搜索以搜索大约2000个不同的文本以查找大约2175个不同的单词时,应用程序将以OutOfMemoryException终止(大约经过6个小时),终止于大约50%

我一直在尝试查找内存泄漏。我有一个像这样的对象图:(->是引用)

静态全局应用程序对象(控制器)->算法启动器对象->文本挖掘启动器对象->文本挖掘算法对象(此对象执行搜索)。

文本挖掘启动程序对象将在单独的线程中启动文本挖掘算法对象的run()方法。

为了尝试解决该问题,我已经编辑了代码,以便文本挖掘入门对象将文本分成几组进行搜索,并依次为每组文本初始化一个文本挖掘算法对象(因此当一个文本挖掘算法对象完成时)将创建一个新的文本来搜索下一组文本)。在这里,我将先前的文本挖掘算法对象设置为null。但这不能解决问题。

当我创建一个新的文本挖掘算法对象时,我必须给它一些参数。这些取自之前的文本挖掘算法对象的属性,然后将该对象设置为null。这样是否可以防止垃圾收集文本挖掘算法对象?

这是文本挖掘算法启动器用于创建新文本挖掘算法对象的代码:

    private void RunSeveralAlgorithmObjects()
    {

        IEnumerable<ILexiconEntry> currentEntries = allLexiconEntries.GetGroup(intCurrentAlgorithmObject, intNumberOfAlgorithmObjectsToUse);

        algorithm.LexiconEntries = currentEntries;
        algorithm.Run();

        intCurrentAlgorithmObject++;

        for (int i = 0; i < intNumberOfAlgorithmObjectsToUse - 1; i++)
        {
            algorithm = CreateNewAlgorithmObject();
            AddAlgorithmListeners();
            algorithm.Run();
            intCurrentAlgorithmObject++;
        }

    }

    private TextMiningAlgorithm CreateNewAlgorithmObject()
    {
        TextMiningAlgorithm newAlg = new TextMiningAlgorithm();

        newAlg.SortedTermStruct = algorithm.SortedTermStruct;
        newAlg.PreprocessedSynonyms = algorithm.PreprocessedSynonyms;
        newAlg.DistanceMeasure = algorithm.DistanceMeasure;
        newAlg.HitComparerMethod = algorithm.HitComparerMethod;
        newAlg.LexiconEntries = allLexiconEntries.GetGroup(intCurrentAlgorithmObject, intNumberOfAlgorithmObjectsToUse);
        newAlg.MaxTermPercentageDeviation = algorithm.MaxTermPercentageDeviation;
        newAlg.MaxWordPercentageDeviation = algorithm.MaxWordPercentageDeviation;
        newAlg.MinWordsPercentageHit = algorithm.MinWordsPercentageHit;
        newAlg.NumberOfThreads = algorithm.NumberOfThreads;
        newAlg.PermutationType = algorithm.PermutationType;
        newAlg.RemoveStopWords = algorithm.RemoveStopWords;
        newAlg.RestrictPartialTextMatches = algorithm.RestrictPartialTextMatches;
        newAlg.Soundex = algorithm.Soundex;
        newAlg.Stemming = algorithm.Stemming;
        newAlg.StopWords = algorithm.StopWords;
        newAlg.Synonyms = algorithm.Synonyms;
        newAlg.Terms = algorithm.Terms;
        newAlg.UseSynonyms = algorithm.UseSynonyms;

        algorithm = null;

        return newAlg;
    }
Run Code Online (Sandbox Code Playgroud)

这是运行整个搜索过程的线程的开始:

            // Run the algorithm in it's own thread
            Thread algorithmThread = new Thread(new ThreadStart
                (RunSeveralAlgorithmObjects));
            algorithmThread.Start();
Run Code Online (Sandbox Code Playgroud)

这里可以防止以前的文本挖掘算法对象被垃圾回收吗?

Ste*_*ary 5

我建议首先确定泄漏的是什么。然后假设一个原因(例如事件处理程序中的引用)。

要识别泄漏的内容:

  1. 为项目启用本机调试。Properties -> Debug ->检查Enable unmanaged code debugging
  2. 运行程序。由于内存泄漏可能是逐渐发生的,因此您可能不需要让它运行整个6个小时;只是让它运行一段时间然后Debug -> Break All
  3. 调出立即窗口。 Debug -> Windows -> Immediate
  4. 根据您运行的是32位还是64位,.NET 2.0 / 3.0 / 3.5或.NET 4.0,在立即窗口中键入以下内容之一:

    .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll 适用于32位.NET 2.0-3.5

    .load C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\sos.dll 适用于32位.NET 4.0

    .load C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\sos.dll 适用于64位.NET 2.0-3.5

    .load C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\sos.dll 适用于64位.NET 4.0

  5. 现在,您可以在立即窗口中运行SoS命令。我建议检查的输出!dumpheap -stat,如果仍然无法确定问题,请检查!finalizequeue

笔记:

  • 如果已将VS设置为加载符号,则在启用本机调试后首次运行该程序可能需要很长时间(几分钟)。
  • 我建议两者的调试器命令都以!(感叹号)开头。

这些说明来自Microsoft 令人难以置信的TessAdvanced .NET Debugging的作者Mario Hewardt 。

一旦你确定了泄漏而言,其对象发生泄漏,那么假定的原因和执行修复。然后,您可以再次执行这些步骤,以确定该修复程序是否有效。