如何从IEnumerable释放内存

时间:2018-06-28 13:46:54

标签: c# memory-management out-of-memory ienumerable

我正在制作一个程序,该程序在C#中打印出Collat​​z树中的所有节点。 这会占用大量内存,outOfMemoryExceptions已经成为日常工作。该程序的基础如下:

        var fileStream = File.Create("collatz.txt"); //just print into a textfile for testing
        var writer = new StreamWriter(fileStream);

        IEnumerable<Node> nodeList = new List<Node>()
        {
            new Node(1, null) //rootNode
        };
        Task flushTask = Task.CompletedTask;
        while (nodeList.Any())
        {
            var tempList = CalcChildren(nodeList); //Return a IEnumerable of children of all the parents in the nodeList
            await flushTask;
            foreach (var node in tempList)
                writer.WriteLine($"{node.Value} -> {node.Parent.Value}: {node.StepsFromRoot}");
            flushTask = writer.FlushAsync();
            nodeList = tempList;
        }

        writer.Close();

    static IEnumerable<Node> CalcChildren(IEnumerable<Node> parents)
    {
        foreach(var parent in parents)
            foreach (var child in CalcChildren(parent))
                yield return child;
    }

    static IEnumerable<Node> CalcChildren(Node parent)
    {
        var multiValue = parent.CalcMultiplicationValue();
        if (multiValue.HasValue)
        {
            var child = new Node(multiValue.Value, parent);
            parent.MultiplicationChild = child;
            yield return child;
        }
        var divValue = parent.CalcDivisionValue();
        if (divValue.HasValue && divValue.Value!=1)
        {
            var child = new Node(divValue.Value, parent);
            parent.DivisionChild = child;
            yield return child;
        }
    }

我认为这是问题所在,但出于完整性考虑,使用Node类:

    public class Node
{
    public Node(int value, Node parent)
    {
        Value = value;
        Parent = parent;
        if (parent != null)
            StepsFromRoot = parent.StepsFromRoot+1;
        else
            StepsFromRoot = 0;
    }

    public int Value { get; }
    public Node Parent { get; set; }

    public Node DivisionChild { get; set; }

    public Node MultiplicationChild { get; set; }

    public int StepsFromRoot { get; set;  }

    public int? CalcMultiplicationValue()
    {
        if(Value<=int.MaxValue/2)
            return 2 * Value;
        return null;
    }

    public int? CalcDivisionValue()
    {
        double newValue = (Value - 1) / 3.0;
        if (newValue % 2 == 1 && newValue >= 1)
            return (int)newValue;
        return null;
    }
}

我正在尽力减少尽可能多的内存,但这似乎没有用。在第105次迭代左右,该程序占用4 GB内存!我最初以为这是因为我的作家的缓冲区占用了所有内存。现在我认为是因为垃圾收集器没有清理节点的集合。

我试图使它最小化。但是我不确定要删除什么内容同时又要使其完整。预先感谢!

0 个答案:

没有答案