Situation
According to this accepted answer , if " GC" sees a circular link of 2 or more objects that no other objects or GC permanent handles reference, these objects will be assembled. "
I wanted to know if garbage collection works for a super simple tree structure that does not even have content, but only tree nodes with parent and child links.
Imagine that you create a root node, add a child to it, and then a child for the child, etc., so this is actually not a tree, but more like a list (each node has at most one child and one parent).
If you then remove the root child and all the node references inside this child subtree, as I understand the answer above, the garbage collector should clear the subtree.
Description of the problem
If you look at the main method in the test code below, when exe is running from the Release directory, I get the behavior that I would expect , memory consumption increased to ~ 1 GB, then decreases to ~ 27 MB (after 1. GC. collect) again and then again to ~ 27 MB (for 2. GC.collect).
Now, when it runs in the debugger , the memory consumption for this increases to ~ 1 GB, and the memory consumption 1.GC.collect remains where it was then, reaches 1.6 GB, the second for the cycle takes ages, and then I finally get an OutOfMemoryException in the 2nd for-loop.
?
, - ?
- Visual Studio 2010 Express Edition
- GC.Collect() , , . ( )
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Tree
{
class Program
{
static void Main(string[] args)
{
TreeNode root = new TreeNode(null);
TreeNode node = root;
for (int i = 0; i < 15000000; i++)
{
TreeNode child = new TreeNode(node);
node = child;
}
root.RemoveChild(root.Children[0] );
node = root;
GC.Collect();
for (int i = 0; i < 15000000; i++)
{
TreeNode child = new TreeNode(node);
node = child;
}
root.RemoveChild(root.Children[0]);
node = root;
GC.Collect();
Console.ReadLine();
}
}
}
, ,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Tree
{
class TreeNode
{
public TreeNode Parent { get; private set; }
public List<TreeNode> Children { get; set; }
public TreeNode(TreeNode parent)
{
Children = new List<TreeNode>();
Parent = parent;
if(parent != null)
parent.AddChild(this);
}
public TreeNode(TreeNode parent, List<TreeNode> children)
{
Children = new List<TreeNode>();
Parent = parent;
if (parent != null)
parent.AddChild(this);
Children = children;
}
public void AddChild(TreeNode child)
{
Children.Add(child);
}
public void RemoveChild(TreeNode child)
{
Children.Remove(child);
}
}
}