c# - 如何从 IEnumerable 中释放内存
问题描述
我正在制作一个程序,在 C# 中打印出 Collatz 树中的所有节点。这会占用大量内存,并且 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 内存!我首先认为这是因为我的 writer 的缓冲区占用了所有内存。现在我认为这是因为垃圾收集器没有清理节点的集合。
我试图让它更小。但我不确定在保持完整的同时删除什么。提前致谢!
解决方案
推荐阅读
- r - 如何将截距拟合到 ggplot 线性模型图中的特定值?
- ibm-datapower - 如何在 Datapower 中配置 Json Settings 对象
- f# - 如何使用 FSharp.Compiler.Services 的结果
- c# - 为什么 WebSocket4Net 使用 1011 错误代码关闭连接
- c++ - 为什么我不能在 Windows 的 rabbitmq 中创建队列?
- javascript - 为什么我的 setState 函数会覆盖当前状态?
- ionic-framework - 通过文件传输插件 ionic 3 发送多个图像
- amazon-web-services - 如果节点数量达到阈值,是否可以使用 Kubernetes Cluster Autoscaler 来扩展节点?
- c - 如何将 asn1_create_element 用于嵌套方案?
- reactjs - 为什么在 redux 开发工具中更新了状态,但在真实状态 redux 中没有更新