gpt4 book ai didi

c# - 关于垃圾收集 C# .NET 的问题

转载 作者:太空狗 更新时间:2023-10-29 22:34:51 26 4
gpt4 key购买 nike

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

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

一个静态的全局应用对象( Controller )-->一个算法启动对象-->文本挖掘启动对象-->文本挖掘算法对象(这个对象执行搜索)。

文本挖掘启动器对象将在单独的线程中启动文本挖掘算法对象的 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 the algorithm in it's own thread
Thread algorithmThread = new Thread(new ThreadStart
(RunSeveralAlgorithmObjects));
algorithmThread.Start();

这里有什么可以阻止以前的文本挖掘算法对象被垃圾收集吗?

最佳答案

我建议首先确定泄漏的具体内容。 然后假设原因(例如事件处理程序中的引用)。

确定泄漏的内容:

  1. 为项目启用 native 调试。 Properties -> Debug -> 选中 Enable unmanaged code debugging
  2. 运行程序。由于内存泄漏可能是渐进的,您可能不需要让它运行整整 6 个小时;让它运行一段时间,然后 Debug -> Break All
  3. 调出即时窗口。 调试 -> Windows -> 立即
  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 设置为加载符号,则在启用 native 调试后首次运行程序可能需要很长时间(几分钟)。
  • 我推荐的调试器命令都以 !(感叹号)开头。

这些说明由令人难以置信的 Tess 提供来自 Microsoft 和 Advanced .NET Debugging 的作者 Mario Hewardt .

根据哪个对象泄漏确定泄漏后,然后假设原因并实现修复。然后您可以再次执行这些步骤以确定修复是否有效。

关于c# - 关于垃圾收集 C# .NET 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3429754/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com