我需要能够快速查找这些数据,并且需要访问所有的数据。不幸的是,我还需要节省内存(多个数据可能会导致OutofMemoryExceptions
)。
short[,,] data = new short[8000,8000,2];
我已经尝试过以下方法:
- 尝试了不规则数组 - 仍然遇到了内存问题
- 尝试将其分成更小的数组 - 仍然会出现内存问题
- 唯一的解决方法是使用内存映射文件有效地映射这些数据,还是有其他方法可以做到这一点?
我需要能够快速查找这些数据,并且需要访问所有的数据。不幸的是,我还需要节省内存(多个数据可能会导致OutofMemoryExceptions
)。
short[,,] data = new short[8000,8000,2];
那么一个数据库怎么样?毕竟它们就是为此而生的。
我建议您看一些NoSQL数据库。根据您的需求,还有可以复制部署或链接到应用程序的内存数据库[显然也可能遇到同样的内存问题]和数据库。
我不想手动处理存储细节,而内存映射文件正是某些数据库(至少是MongoDB)在内部正在执行的操作。因此,实质上,您将会编写自己的数据库,并且编写数据库并不是一件简单的事情--即使您缩小了使用案例。
Redis或Membase听起来是解决您问题的合适选择。就我所知,两者都能够为您管理RAM利用率,即按需从磁盘读取数据并在RAM中缓存数据以实现快速访问。当然,您的访问模式将在此处发挥作用。
请记住,建立这些数据库需要付出大量的努力。根据维基百科,Zynga正在使用Membase,Redis由VMWare赞助。
你确定你需要一直访问所有数据吗?或者你可以只加载部分数据,进行处理,然后再转到下一个部分吗?
如果只是高度数据,你能否使用 mip-mapping 或 LoD 表示来减少数据量?这两种方法都可以让你保留低分辨率的数据,直到你需要加载更高分辨率的数据块。
你的机器上有多少可用内存?你使用的操作系统是什么?是 64 位的吗?
如果你正在进行内存/处理密集型操作,是否考虑将这些部分实现为 C++,以便更好地控制这些事情?
如果不知道你的系统的一些具体信息和你正在处理的数据是什么,我们很难提供更进一步的帮助...?
如果您正在使用此数据进行数字计算,我不建议使用传统的关系型数据库。我怀疑您在这里遇到的问题并不是数据本身的大小,而是 .NET 中已知的一个问题,称为大对象堆碎片。如果您经常分配这些缓冲区后遇到问题(即使它们应该被垃圾回收),那么这很可能是罪魁祸首。您最好的解决方案是预先分配尽可能多的缓冲区并重复使用它们,以防止重新分配和随后的碎片化。
你是如何与这个大型多维数组进行交互的?你使用递归吗?如果是的话,请确保你的递归方法是通过引用传递参数,而不是通过值传递。
顺便说一下,你是否需要同时访问100%的数据?处理大量数据的最佳方式通常是通过流或某种读取器对象。尝试按段处理数据。我有一些处理几十GB数据的过程,由于我是通过SqlDataReader以流的方式读取数据,所以它可以在很少的内存中处理。
简而言之:看看你如何在函数调用之间传递数据(O(ref)),也许可以使用流式处理模式来处理较小的数据块。
希望对你有所帮助!
.NET将shorts存储为32位值,即使它们只包含16位。因此,您可以通过使用int数组并使用位操作将int解码为两个shorts来节省一倍的空间。
然后,您几乎拥有了存储此类数组的最有效方法。然后您可以:
使用64位机器。然后,您可以分配大量内存,如果您的RAM用完,操作系统会自动将数据分页到磁盘上(确保您有足够大的交换文件)。然后,您可以使用8 TERA字节的数据(如果您有足够大的磁盘)。
手动使用文件IO或使用内存映射从磁盘中读取需要的数据部分。
new short[8000,8000,2]
的大小只有 256,000,000 字节。你确定内存中没有其他对象导致这些异常吗? - Jeffrey L Whitledge