2010-06-23 19 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

相關問題