Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构建非重组三项式树时如何避免c#中的System.OutOfMemoryException_C#_List_Memory Management_Out Of Memory - Fatal编程技术网

构建非重组三项式树时如何避免c#中的System.OutOfMemoryException

构建非重组三项式树时如何避免c#中的System.OutOfMemoryException,c#,list,memory-management,out-of-memory,C#,List,Memory Management,Out Of Memory,我“成功”实施了非重组三项式树,为某些固定收益衍生品定价。(如下图所示,但有三个分支无法重新连接) 不幸的是,我可以使用的节点数量受到可用内存的严重限制。如果我构建一个包含20个时间步的树,这将产生3^19个节点(因此有11亿个节点) 每个时间步的节点保存在列表中,这些数组存储在字典中 每个节点都通过新节点(…)实例化。我还通过newclass()实例化了每个列表和字典,也许这就是我的错误根源 另外,System.OutOfMemoryException不会引发,因为Dictionary/Lis

我“成功”实施了非重组三项式树,为某些固定收益衍生品定价。(如下图所示,但有三个分支无法重新连接)

不幸的是,我可以使用的节点数量受到可用内存的严重限制。如果我构建一个包含20个时间步的树,这将产生3^19个节点(因此有11亿个节点)

每个时间步的节点保存在
列表中
,这些数组存储在
字典中

每个节点都通过
新节点(…)
实例化。我还通过
newclass()
实例化了每个列表和字典,也许这就是我的错误根源

另外,
System.OutOfMemoryException
不会引发,因为Dictionary/List对象太大(通常是这样),而是因为我似乎有太多的节点-过一段时间后,
新节点(…)
无法分配任何进一步的内存。最终,2GB的最大列表容量也将开始发挥作用,我认为,随着列表随着时间的推移呈指数级增长

也许我的数据结构太浪费或者不适合手头的任务

一个可能的解决方案是将树保存到文本文件中,从而完全避免内存问题。然而,这需要一个巨大的解决方案

编辑: 添加更多的背景。我需要树来为路径相关的产品定价。这意味着不幸的是,我将不得不访问所有节点。更重要的是,在树建成后,我从树叶开始,然后倒转时间来确定价格。我也已经只生成了我需要的节点

Edit2:
我对这个话题做了一些思考,也考虑了各种反应。可能我只需要将相应的树级别序列化到硬盘驱动器。因此,基本上-我创建一个时间步(
列表
)将其写入磁盘等。稍后,当我从叶子开始时-我只需按相反顺序加载它

我们这里遇到的是一个典型的问题,即预先进行大量处理。。。然后将所有内容存储到内存中,以便以后处理

虽然很简单,但如果条件足够苛刻(比如有十亿个条目),它会消耗掉所有的内存

现在,OP并没有真正说明这棵树的意图是什么,或者如何使用它。。。但我建议不要一次建成所有的。。。根据你的需要建造它

使用
收益率进行惰性评估

而不是一次做所有的事情并且必须存储它。。。只有在你真正需要的时候才去做可能是理想的。有关使用
yield
的更多信息和示例,请查看此文档


但是如果你需要在树上来回移动很多次的话,这就不太好用了。。。但它仍然可以让你拥有比现在更深的深度。

你基本上有两个选择。只评估您关心的分支(Andrew的收益率),不存储结果或构建树并将其保存到磁盘,并在其上实现一个自定义收集接口,以访问磁盘的正确部分。在这种情况下,您仍将在进程内存中保留少量数据,并依靠操作系统进行适当的磁盘缓存以加快访问速度。如果您开始使用大数据集,那么第二个选项是一个很好的工具,可以放在您的工具带中,因此您可能应该在编写时考虑重用。

我认为序列化到磁盘不会有多大帮助。第一,当您尝试反序列化列表时,您仍然会耗尽内存(据我所知,没有办法部分反序列化对象)

您是否考虑过将数据结构更改为关系数据库模型并将其存储在SQLEXPRESS数据库中


这将为您提供使用索引而不是自定义树遍历逻辑执行查询的额外好处。

这是在x64上运行的吗?@AndreyLujankin,您是否将程序编译为64位应用程序来利用这一点,或者您是将其编译为32位应用程序?如果您想提高内存效率,我会避免使用对象,几乎任何东西都可以存储到简单数组中,但这不是一个解决方案,只是将上限提高一点。还要注意的是,列表占用的内存可能是其已用容量的两倍。我想知道允许使用非常大的对象是否是一种解决方法@AndreyLujankin是的,您的
列表不太大。。。但是
字典
有十亿个参考文献。。。所以它可能会很大。注意,在.NET的更高版本中有一些不错的。因此,您可以将整个对象持久化到磁盘,但尽可能多地保留在内存中缓存,当缓存未命中时,您可以转到磁盘重新读取数据。@ScottChamberlain您提到的缓存类看起来非常有趣。我以前从未做过这样的事情:)另一个想法——据我所知,cach恰好在CPU中,而不是磁盘中,或者我混淆了什么吗?@AndreyLujankin缓存是一种通用策略,可以发生在很多地方。对于磁盘缓存,Windows将尝试将经常使用的文件保存在RAM中,以便在执行读取操作时,它只是复制内存,而不是从磁盘读取字节。我相信Scott提到的缓存对象可以用来尝试保持一组可管理的对象,这样您就可以使用磁盘或DB之类的东西来保存完整的集合。@Yaur我理解他的建议。这实际上是有道理的。在任何给定的时间,我只需要树节点一段时间。因此,树的其余部分可以存储在某个地方,并在需要时访问。不幸的是,我没有经验来判断什么是实现这一目标的最佳方法。序列化还是Cac