【问题标题】:Minimizing the memory footprint of an ADO.NET DataSet?最小化 ADO.NET 数据集的内存占用?
【发布时间】:2010-10-15 16:36:20
【问题描述】:

鉴于大量使用 DataSet 的遗留系统,并且很少或根本不可能用业务对象或其他更高效的数据结构替换它们:

是否有任何技术可以减少 DataSet 的内存占用?

我正在考虑设置初始容量(已知时)、删除限制等,但我对 DataSets 的经验很少,不知道哪些特定选项可供我使用,或者它们中的任何一个是否重要全部。

更新:

我知道长期重构的可能性,但我正在寻找快速修复给定存储在 DataSet 中的一组 DataTable 对象,即已知哪些属性会影响内存开销。

由于数据在内部存储的方式,设置初始容量可能是一种方法,因为这将防止对象在仅添加一行时分配任意大量的内存。

【问题讨论】:

    标签: memory ado.net dataset


    【解决方案1】:

    您可以尝试让您的表和行在文件背后的代码中实现接口。然后随着时间的推移更改代码以使用这些接口,而不是直接使用表/行。

    一旦您的大部分代码只使用接口,您就可以使用代码生成来创建实现这些接口的 C# 类,而不会产生行/表的开销。

    不过,迁移到 64 位并购买更多内存可能会更便宜...

    【讨论】:

      【解决方案2】:

      不幸的是,这对您有帮助,但在相同的情况下它可以提供很大的帮助。

      如果您要在数据集中存储大量相同的字符串,例如城镇名称,请查看仅对每个不同字符串使用单个字符串对象。

      例如

      Directory <string, string> towns = new Directory <string, string>();
      foreach(var row in datatable)
      {
          if (towns.contains(row.town))
          {
             row.town = towns[row.town]
          }
          else
          {
             towns[row.town] = row.town;
          }
      }
      

      然后 GC 可以回收大部分重复的字符串,但这仅在数据集存在一段时间时才有效。

      您可能希望在 rowCreated 事件中执行此操作,这样一来就不会创建所有重复的字符串对象。

      【讨论】:

      • 可能是个主意。必须在一些实际数据上对此进行测试,以衡量内存减少和对 CPU 周期的影响。
      【解决方案3】:
      1. 如果您使用的是 VS2005+,您可以实例化 DataTable 对象,而不是整个 DataSet。 2003年,如果实例化DataTable,默认自带DataSet。 2005 年及之后,您只得到 DataTable。

      2. 查看数据访问层以填充数据集或数据表。最常见的情况是通过的数据过多。让您的查询更具体。

      3. 确保您使用的代码在传递数据集时不会做傻事,例如复制数据集。确保您使用 .Select 语句或 DataView 进行过滤和排序,而不是复制。

      DataSet 没有很多快速的“优化”。如果您遇到内存问题,请使用第 2 项和第 3 项。无论您使用哪种类型的数据传输对象,都会出现这种情况。

      并且擅长数据集。如果你不熟悉它们,你可以做一些愚蠢的事情,比如任何事情。然后,您将撰写有关它们如何糟糕的文章,这些文章实际上是关于您对它们知之甚少的文章。它们确实非常有用且易于维护。一些提示:

      • 使用类型化的数据集。它们将为您节省大量的编码,并且它们被输入,这有助于简单的验证。
      • 如果您使用的是类型化 DS,请确保不要修改生成的代码文件。如果您使用的是 VS2005+,则可以将任何自定义业务对象行为放在 DS 的部分类中(而不是 .designer 代码文件)。
      • 使用 DataView 和 .Select 在您发现自己循环遍历 DataRow 对象的任何位置。
      • 四处寻找一个好的代码生成工具,并构建一个合理的数据访问框架,用于从 DS 中填充和更新。问题之一是,有时,设计人员将 DS 的设计直接与数据库中的表联系起来,使得设计对数据结构的更改变得脆弱。如果您必须这样做,请构建或使用代码生成器从数据库构建您的数据访问层,例如 CodeSmith。首先查看一些用于生成存储过程和数据访问类的 CodeSmith 模板。
      • 请记住,在与某人谈论“对象”与“数据集”时,本例中的对象是 DataRow,而不是 DataSet。由于部分类,您可以将行为放在“对象”上,为喜欢编写代码的人带来“对象”的 95% 的好处。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        • 1970-01-01
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多