什么是管理大量数据(高度数据)和替换这个巨大阵列的最有效方法?

时间:2011-06-06 19:40:36

标签: c# .net multidimensional-array out-of-memory

我需要能够快速查找这些数据,并且需要访问所有这些数据。不幸的是,我还需要节省内存(其中一些会导致OutofMemoryExceptions

short[,,] data = new short[8000,8000,2];

我尝试过以下方法:

  • 尝试了锯齿状阵列 - 相同的内存问题
  • 尝试分解成更小的数组 - 仍然会出现内存问题
  • 唯一的解决方案是使用内存映射文件有效地映射此数据,还是有其他方法可以做到这一点?

5 个答案:

答案 0 :(得分:5)

数据库怎么样?毕竟,他们是为此而做的。

我建议你看一些NoSQL database。根据您的需要,还有内存数据库[显然可能会遇到相同的内存不足问题]和可以复制部署或链接到您的应用程序的数据库。

我不想手动搞乱存储细节,内存映射文件是一些数据库(至少是MongoDB)在内部执行的操作。从本质上讲,你将自己编写自己的数据库,编写数据库并非易事 - 即使你缩小了用例范围。

Redis或Membase听起来像是您问题的合适替代品。据我所知,两者都能够为您管理RAM利用率,即根据需要从磁盘读取数据,并将数据缓存在RAM中以便快速访问。当然,您的访问模式将在这里发挥作用。

请记住,构建这些数据库需要付出很多努力。根据维基百科,Zynga正在使用MembaseRedis由VMWare赞助。

答案 1 :(得分:1)

您确定需要一直访问所有这些内容吗? ...或者你可以加载它的一部分,进行处理然后移动到下一个吗?

如果它只是高度数据,你可以使用mip-mapping或LoD表示吗?这两种方法都可以让您保持较低的分辨率,直到您需要加载更高分辨率数据的特定块。

你的机器有多少可用内存?您使用什么操作系统?是64位吗?

如果您正在进行内存/处理密集型操作,您是否考虑过用C ++实现这些部分,以便更好地控制这些部分?

如果不了解系统的更多细节以及您对数据的实际操作,很难帮助您更进一步......?

答案 2 :(得分:0)

如果您使用此数据进行数值计算,我不会推荐传统的关系数据库。我怀疑你在这里遇到的不是数据本身的大小,而是.NET的已知问题Large Object Heap Fragmentation。如果你经常在分配这些缓冲区后遇到问题(即使它们应该被垃圾收集),这可能是你的罪魁祸首。您最好的解决方案是保留尽可能多的预先分配缓冲区并重新使用它们,以防止重新分配和后续碎片。

答案 3 :(得分:0)

你是如何与这个大型多维数组进行交互的?你在使用递归吗?如果是这样,请确保您的递归方法是通过引用而不是按值传递参数。

另外,您是否需要同时访问100%的此类数据?处理大量数据的最佳方法通常是通过流或某种读取器对象。尝试处理细分中的数据。我有一些处理Gigs数据的进程,并且它可以在少量内存中处理它,因为我是通过SqlDataReader将它传输进来的。

TL; DR:看看如何在函数调用O(ref)之间传递数据,并使用流模式处理较小块中的数据。

希望有所帮助!

答案 4 :(得分:0)

.NET将short存储为32位值,即使它们只包含16位。因此,你可以使用一个int数组来保存一个因子2,并使用位操作将int解码为两个短路。

然后你几乎拥有存储这样一个数组的最有效方法。你能做的是:

  1. 使用64位计算机。然后,您可以分配大量内存,如果RAM用完,操作系统将负责将数据分页到磁盘(确保您有足够大的交换文件)。然后你可以使用8个TERAbytes数据(如果你有足够大的磁盘)。

  2. 使用文件IO或使用内存映射手动从磁盘中读取部分数据。