处理大量RAM工作集的技巧

时间:2010-01-29 20:56:40

标签: algorithm memory-management

我正在开发专为高性能PC设计的.Net 3.5应用程序,它可以进行大量的数据操作和计算。我最近遇到了一个4000 x 5000二维对象数组的需求,这对于32位PC来说非常大,并且会给我一个OutOfMemoryException。避免使用像这样的阵列的唯一方法是沿着一条充满痛苦和痛苦的非常复杂,耗时的道路走下去。

专业人员是否有任何提示或技巧来处理大型工作RAM?你知道任何有用的库(特别是.Net)吗?有没有办法强制Windows为我的进程分配更多的RAM?

编辑: 我正在使用的数组将主要包含空引用,我使用该数组来跟踪相邻的对象。看到它们中的大多数是空引用,我还假设有一种更有效的方法来跟踪相邻对象,为任何给定对象找到邻居等。

7 个答案:

答案 0 :(得分:7)

根据您的评论,我想我现在可以回答您的问题了。如果大多数引用都为null,那么您可以将键散列到一个表中,该表又指向您的元素。在哈希映射中有恒定的时间O(1)循环时间,您不必担心密钥冲突,因为每个[x,y]对都是唯一的。您也不必担心内存冲突,因为大多数引用都是null。

答案 1 :(得分:1)

嗯,有人想过要废弃数据库的二维数组。像SQLite这样的东西占地面积很小,可以很容易地与应用程序一起部署。它甚至有一个C# wrapper

SQLite将从单个文件中读取此数据。因此,磁盘的读写操作可能会受到性能影响。虽然性能受到多大影响可能取决于应用程序的性质。例如,通过索引查找应该很快。但是整个数据库的大量计算肯定会变慢。所以...我不知道,但也许值得考虑。

答案 2 :(得分:1)

您可以有效地存储类似网格的结构,其中大多数元素在稀疏数组中为空。它们可以以不同的方式实现,但通常使用行和列的修改的链接列表。有一个很好的介绍主题here

答案 3 :(得分:1)

如果你的大部分元素都是null,那么你可能根本不需要创建一个数组。

Jon建议一种方法可行 - 使用链表实现稀疏数组。这是另一个:

public struct CellLocation
{
   int Row;
   int Column;
}

public class Element
{
   public Element(int row, int column)
   {
      Location = new CellLocation {Row = row, Column=column};
   }

   public readonly Location { get; private set; }

   // your class's other properties and methods go here
}

现在,您可以将Element个对象存储在Dictionary<CellLocation, Element>中。实际上,我将该字典放入自己的类中,以便它可以实现如下方法:

public IEnumerable<Element> AdjacentElements(Element elm)
{
   for (int row = -1; row <= 1; row++)
   {
      for (int column = -1; column <= 1; column++)
      {
         // elm isn't adjacent to itself
         if (row == 0 && column == 0)
         {
            continue;
         }
         CellLocation key = new CellLocation { 
            Row=elm.Location.Row + row, 
            Column=elm.Location.Column + column 
         };
         if (!Cells.ContainsKey(key))
         {
            continue;
         }
         yield return Cells[key];
      }
   }
}

有些操作可以比稀疏数组更快。要在单个行和列中查找元素,稀疏数组仍然必须执行线性搜索以查找行,然后进行另一个线性搜索以查找该行中的列,而此方法可以找到一个查找到的行的元素哈希表。

在某些情况下,它会慢得多。要查找行中的所有元素,需要与行中的单元格一样多的哈希表查找,而使用稀疏数组执行此操作只需要遍历链接列表。

答案 4 :(得分:0)

数组是否已修复?即数组中的值不会改变...将数组内容转储到磁盘并使用内存映射技术可能是值得的,然后您可以将转储数组的一部分加载到内存映射中以供读取。 。如果数组中的数据和元素发生变化,它将不会这样做......

只是我的2点......

希望这有帮助, 最好的祝福, 汤姆。

答案 5 :(得分:0)

在操作系统或流程级别有2个“简单”方向。

  1. /3GB switch添加到您的帐户中 boot.ini和modify your app to use /LARGEADDRESSAWARE。您可以立即获得额外的1G虚拟地址空间,但不能没有a tradeoff。好 它是正确的选择 您。
  2. 问题往往不是 缺乏的记忆,而是 它的碎片 - 似乎也与您的上下文相关 (巨大的连续数组)。一会儿 我曾在网上some techniques that helped me进行战斗 本机代码的碎片 - 应该至少部分适用于托管。

答案 6 :(得分:0)

看起来你实际在做的是一个邻接矩阵。如果是这种情况,并且底层图是稀疏的,那么切换到邻接列表可能会更好。 http://en.wikipedia.org/wiki/Adjacency_list