【问题标题】:In C#, what is the smallest memory footprint way of storing database rows in memory for processing?在 C# 中,将数据库行存储在内存中进行处理的最小内存占用方式是什么?
【发布时间】:2010-06-23 23:08:04
【问题描述】:

我对 C# 编程有点陌生,需要一些关于如何解决问题的建议。我需要处理存储在 SQL Server 数据库中的数万条记录,并且处理速度应该尽可能快。

为了最大限度地提高性能,我在应用程序启动时在后台线程上从数据库中获取行,因为它需要在开始处理之前等待一些用户输入。这种方法节省了整个过程 20% 的时间,但在内存占用方面非常消耗资源(该过程占用 200MB 的 RAM,我估计数据库行的原始数据不到 10MB)。

我正在使用一个类,其成员存储数据库列中的数据,并使用 ArrayList 来存储行。

是否有另一种方法将数据存储在内存中以最小化消耗的内存?

【问题讨论】:

  • 我希望我们谈论的是一些非常复杂的处理......否则存储过程(带有用于您的用户输入的参数)(或类似的)会是处理您的数据的更合适的机制吗?处理存储的数据是 SQL Server 非常擅长的。
  • 只是为了让事情更清楚:该应用程序是一个生物指纹识别系统。在生物特征从某人那里收集手指模板的同时,在数据库中获取存储的手指模板可以使整个识别过程更快。

标签: c# memory-management


【解决方案1】:

您应该知道,任务管理器中指示的内存使用量并不一定是数据使用的内存。该程序占用的内存比它目前需要的多,以便能够很好地扩展。如果您想了解究竟使用了多少内存,请使用内存分析器。

【讨论】:

【解决方案2】:

列的数据类型是什么?

如果有很多字符串,那么您可能会受到字符串开销的影响。 .NET 字符串是 UTF-16(每个字符 2 个字节)并且(我认为)每个字符串有 16-18 个字节的开销。如果您确实需要节省内存,并且数据是 ASCII,您可以考虑使用 Encoding.UTF8 将多个字符串列组合成一个字节数组。

// Occupies 64 bytes of memory
string col1 = "Me", col2 = "You", col3 = "Us";

StringBuilder sb = new StringBuilder(col1);
// only works if you are sure the columns have no nulls
sb.Append('\0');
sb.Append(col2);
sb.Append('\0');
sb.Append(col3);

// Occupies 24 bytes of memory
byte[] array = Encoding.UTF8.GetBytes(sb.ToString());

当然,这会减慢程序的速度,并且当您需要取出字符串时,您必须编写代码来解压字节数组,但您可能会节省大量内存。

【讨论】:

  • 1个CHAR(6)列,3个INT和1个IMAGE列,存储不超过900字节。
  • 我想我当时没有帮忙。您可以使用 CLR 分析器查看内存的去向:microsoft.com/downloads/… - 我假设 IMAGE 列是位图;如果使用 .NET 图像或位图来保存数据,请确保它的位深度不大于原始图像。
【解决方案3】:

在不了解您的应用的更多详细信息的情况下需要检查的一些基本事项:

  • 您是否只在内存中存储您需要的内容?
  • 您是否在Large Object Heap 上创建内容?这可能不会被收集。
  • 您能否分批处理数据,并将每批的结果减少到另一个中间内存/磁盘存储中?本质上,您可以使用某种形式的 map-reduce 吗?
  • 使用WinDBG to look at your heap 并查看有根对象。它会让您更好地了解 200MB 中的内容。

【讨论】:

    【解决方案4】:

    “我正在使用有成员的课程”可能是您的问题。原始数据类型(如 bool、int 等)应该需要与您的数据库中大致相同的空间。但是当您创建一个类的新实例时,必须在堆上保留额外的数据。现在,仅处理“数万”行时,这不应该占 200MB,但您可以尝试使用值类型(例如,将您的类更改为结构)。

    此外,如果您的数据库包含每个长度大致相同的字符串,您可以使用字符数组来存储它们以“最小化消耗的内存”。

    【讨论】:

    • 我尝试使用结构而不是类来存储值,但在进程大小方面没有明显差异。
    • 好吧,也许您的应用程序的核心内存占用非常小,并且正如其他答案所暗示的那样,runtume 环境的大部分 200mb 帐户。使用结构背后的想法是将它们全部存储在一个连续的内存块中,从而避免每个对象实例化的额外数据。
    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 2021-04-24
    • 2011-07-06
    • 2011-04-05
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多