Yesterday I decided to try my hand at a chess playing program since in my many years I realized I had never written a chess program. I created an AI that evaluates many possible moves/positions and consumes lots of memory. But I figured it would be OK if I cut off my reference to that data each turn. I should get the memory back when needed. But for some reason the objects are sticking in memory. Even when I call GC.Collect()
I find that memory usage does not go down, and, thanks to the new GetGeneration
method of GC
I can see that my objects are stuck in generation 2 (I'm using weak references to hold on to them for the purpose of passing to GetGeneration
, of course). The code is not as large as one might think a chess program with an AI would be. It's at https://github.com/bluemonkmn/Chess. Locally I have changed the Program.cs
file to make a weak reference to the local board
variable. Then I have some code to try to eliminate my reference and check the garbage collection:
board = board.Clone();
validMoves.Clear();
Console.WriteLine(GC.GetGeneration(wr));
GC.Collect(2);
GC.WaitForFullGCComplete();
GC.WaitForPendingFinalizers();
Console.WriteLine(GC.GetGeneration(wr));
The Clone
function (which you can see in the original project if you like - linked above) should be making a copy without any references to old data. And I can't find any other references to old objects. Yet both calls to GC.GetGeneration(wr)
output 2
. This program's data structure doesn't seem that terribly complicated. I don't have that many variables in the main function so it's not hard to track them down and see what references could be held. Where could the reference to the old board object possibly be coming from?
As far as I can tell, the only variable that could be holding a reference directly or indirectly to ChessBoard
objects is the board
variable in the Play
function in Program.cs
. Everything else is using pure .NET framework types that can't reference my arbitrary types.