C# 无法确定第2代对象引用的源

C# 无法确定第2代对象引用的源,c#,memory-leaks,garbage-collection,C#,Memory Leaks,Garbage Collection,昨天我决定尝试下一个国际象棋程序,因为多年来我意识到我从来没有写过一个国际象棋程序。我创建了一个人工智能,可以评估许多可能的移动/位置,并消耗大量内存。但我想,如果我每回合都切断对该数据的引用,那就没问题了。我应该在需要的时候找回记忆。但由于某种原因,这些物体会粘在记忆中。甚至当我调用GC.Collect()时,我发现内存使用率没有下降,而且,由于GC的新GetGeneration方法,我可以看到我的对象被卡在第2代中(当然,我使用弱引用来保持它们,以便传递到GetGeneration)。代码并

昨天我决定尝试下一个国际象棋程序,因为多年来我意识到我从来没有写过一个国际象棋程序。我创建了一个人工智能,可以评估许多可能的移动/位置,并消耗大量内存。但我想,如果我每回合都切断对该数据的引用,那就没问题了。我应该在需要的时候找回记忆。但由于某种原因,这些物体会粘在记忆中。甚至当我调用
GC.Collect()
时,我发现内存使用率没有下降,而且,由于
GC
的新
GetGeneration
方法,我可以看到我的对象被卡在第2代中(当然,我使用弱引用来保持它们,以便传递到
GetGeneration
)。代码并不像人们想象的带有AI的国际象棋程序那么大。它在。在本地,我更改了
Program.cs
文件,对本地
board
变量进行了弱引用。然后我有一些代码试图消除我的引用并检查垃圾收集:

board = board.Clone();
validMoves.Clear();
Console.WriteLine(GC.GetGeneration(wr));
GC.Collect(2);
GC.WaitForFullGCComplete();
GC.WaitForPendingFinalizers();
Console.WriteLine(GC.GetGeneration(wr));
Clone
函数(如果您愿意,可以在原始项目中看到它-上面链接)应该在不引用旧数据的情况下进行复制。我找不到任何其他关于旧物体的引用。然而,这两个调用都是对
GC.GetGeneration(wr)
output
2
。这个程序的数据结构似乎没有那么复杂。我在主函数中没有那么多的变量,所以不难找到它们并查看可以保存哪些引用。对旧board对象的引用可能来自哪里


据我所知,唯一可以直接或间接引用
棋盘
对象的变量是
Play
函数中
Program.cs
中的
board
变量。其他所有东西都使用纯.NET framework类型,无法引用我的任意类型。

阅读后,我发现在调试模式下引用的根生成可能与在发布模式下不同。我发现在没有附加调试程序的情况下以释放模式运行时返回了所有内存。它在发布模式下的运行速度也明显加快。我一直期望发布模式和调试模式之间会有一些不同,但这是我第一次看到内存使用和性能有如此显著的差异。

您有什么理由认为需要调用
GC.Collect()
?程序的内存使用率没有下降并不表示需要调用GC.Collect(),也不一定表示内存泄漏。在几乎所有情况下,最好让GC在需要时运行。这只是一种调试措施。我希望立即报告wr的生成,以便了解是否存在内存泄漏。显然有一种是因为它是在第二代,而不是在GC之后。收集。是程序速度明显减慢,还是您刚刚查看了Windows任务管理器?速度很慢,但我不认为是内存使用造成的。我只是担心如果我以高智商下一盘完整的国际象棋,会出现记忆问题。只需几次移动,内存使用量(任务管理器)就从每次移动约200 MB增加到超过1 GB。我知道.NET内存管理器应该是非常智能的,但我不想知道内存泄漏是怎么回事,所以我尝试在出现实际问题之前对其进行分析。VS profiler告诉我,由于某种原因,内存中锁定了200000多个对象,所以我只看其中一个。