0

从数据库中获取时,我的应用程序中遇到 OutOfMemory 异常。它是一个使用 Linq2Sql 的 C# .Net 应用程序。

我尝试使用GC.GetTotalMemory()来查看调用数据库之前和之后占用了多少内存。这对正在发生的事情给出了一个很好的虽然不是很准确的画面。当我查看 Windows 任务管理器时,我可以看到峰值工作集在使用以下代码以分页方式获取数据时并不小:

public static void PreloadPaged()
{
    int NoPoints = PointRepository.Count();
    int pagesize = 50000;
    int fetchedRows = 0;

    while (fetchedRows < NoPoints)
    {
        PreloadPointEntity.Points.AddRange(PointRepository.ReadPaged(pagesize, fetchedRows));
        PointRepository.ReadPointCollections();
        PreloadPointEntity.PointCollections.Count());
        fetchedRows += pagesize;
    }
}


private static List<PointEntity> ReadPaged(int pagesize, int fetchedRows)
{
    DataModel dataContext = InstantiateDataModel();
    var Points = (from p in dataContext.PointDatas
                select p.ToEntity());

    return Points.Skip(fetchedRows).Take(pagesize).ToList();
}

我猜是 Linq2Sql 代码用尽了内存而不是重用它或之后释放它,但我能做些什么来降低内存足迹?

我观察到它使用 10 倍的内存来获取数据,因为它将它们存储在我的实体列表中。我考虑过调用垃圾收集器,但我宁愿避免它。

4

1 回答 1

2

您正在检索太多数据并将其存储在内存中,这就是您收到 OOM 异常的原因。

发生 2 件事中的 1 件:

  1. 当用户只会查看结果的子集和/或这是第一次尝试“缓存”数据时,您正在加载过多的数据。
  2. 您确实需要所有这些数据,但使用了错误的技术 (Linq2Sql) 来访问数据。

如果是第一个,您需要

  1. 加载较小的数据块(20-50 条记录,而不是 50K 或所有内容)
  2. 如果这仅用于显示目的,则查询所需内容的投影,而不是实体本身。

如果它是第二个而不是使用旨在管理大量数据的 ETL 工具。我更喜欢Rhino.ETL但 SSIS 也可以。

于 2012-06-21T10:57:24.070 回答