2010-06-23 20 views
0

我对C#编程有点新,并且需要一些关于如何解决问题的建议。我需要处理存储在SQL Server数据库上的数以万计的记录,并且处理过程应尽可能快。在C#中,存储器中用于处理数据库行的最小内存占用方式是什么?

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

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

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

+1

我希望我们正在谈论一些非常复杂的处理...否则,存储过程(用于用户输入的参数)(或类似的)是否是更适合处理数据的机制?处理存储的数据是SQL Server所做的很好的事情。 – Reddog 2010-06-23 23:30:43

+0

只是为了使事情更清楚:应用程序是一个生物识别手指识别系统。当生物特征从某人身上采集手指模板时,在数据库中抓取存储的手指模板可以使识别的整个过程更快。 – LrycXC 2010-06-24 01:06:42

回答

1

您应该意识到,taskmanager中指示的内存使用情况不是数据所使用的内存所必需的。该计划抓住比目前需要更多的内存,以便能够很好地扩展。如果你想知道有多少内存正确使用,请使用内存分析器。

+0

.NET并没有比它需要的更多。 – Qwertie 2010-06-23 23:41:57

+0

你能指出一个好的内存分析器吗? – LrycXC 2010-06-24 01:11:10

+0

http://www.red-gate.com/products/ants_memory_profiler/index.htm?utm_source=google&utm_medium=cpc&utm_campaign=antsmemoryprofiler&gclid=CNDoo3Gt6ICFdMq3godYgbV6Q – Femaref 2010-06-24 01:15:34

1

一些基本的东西来检查,而无需了解您的应用程序的详细信息:

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

我来看看WinDBG,谢谢! – LrycXC 2010-06-24 01:10:18

1

什么是列的数据类型?

如果有很多字符串,那么你可能会遭受字符串开销。 .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()); 

当然,这会减慢程序,你不得不编写代码来解压缩字节数组,当你需要得到的字符串,但是你可能会节省大量的内存。

+0

有一个CHAR(6)列,三个INT和一个IMAGE列,存储不超过900个字节。 – LrycXC 2010-06-24 01:08:43

+0

我想我没有帮助。您可以使用CLR分析器查看内存的位置:http://www.microsoft.com/downloads/details.aspx?FamilyId=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en - 我假设IMAGE列是一个位图;如果使用.NET图像或位图来保存数据,请确保它没有比原始图像更大的位深度。 – Qwertie 2010-06-25 14:08:39

0

“我正在使用带有成员的类”可能是您的问题。像bool,int等原始数据类型应该大致需要与您的数据库中相同的空间。但是,当您创建一个新类的实例时,必须在堆上保留其他数据。现在,只处理“成千上万”行时,这不应该占用200MB,但您可以尝试使用值类型(例如,将您的类更改为结构体)。另外,如果您的数据库包含的字符串长度大致相同,您可以使用char数组来存储它们以便“尽量减少占用的内存”。

+0

我试图使用结构而不是类来存储值,但它在进程大小方面没有明显差异。 – LrycXC 2010-06-24 01:12:35

+0

好吧,也许你的应用程序的核心有一个非常小的内存空间,其他答案显示,大多数200mb的帐户适用于runtume环境。使用结构背后的想法是将它们全部存储在连续的内存块中,从而避免每个对象实例化的附加数据。 – 2010-06-24 10:52:16

相关问题