設計: 我的C#WCF進程必須緩存大量數據在內存中(作爲字典) - 進程佔用的內存增長超過1.5GB。 Cache中的數據或多或少來自數據庫(使用實體框架)。構建緩存的方式是: 在表上選擇查詢以從表中獲取主鍵列表(比如說字符串列表)。假設我獲得了1000個項目的列表。 現在我在這個主鍵列表上執行Parallel.Foreach,並且(foreach)主體的操作是去數據庫並獲取這個鍵的所有數據(即,從KeyColumn = loop項目的表中選擇*)。對數據應用一些操作,然後將其添加到緩存(字典)中。Parallel.Foreach被凍結,但服務繼續響應
問題: 當進程/可執行文件啓動時。它消耗幾乎95%的CPU(這是好的),並佔用RAM(比如1.3或1.4 GB)。運行良好,直到第一次10-12分鐘。但是,由於沒有已知的原因,CPU在內存下降到15-17%,穩定在1.4GB(還有更多)。而且我可以看到數據庫中的幾個項目尚未添加到緩存中。這種凍結的狀態會持續很長時間(有時甚至是10小時),然後所有事情都會處理,所有數據都在我的緩存中。 RAM現在穩定在1.5GB左右。我認爲GC循環會凍結應用程序線程,但之後(因爲它是WCF服務)任何Service方法調用都會做出響應。它唯一的並行線程部分似乎每次都凍結,每次重新啓動都在相同的RAM大小。 我已經驗證了那些notoriusly缺少的鍵的數據沒有什麼不同。
尋找什麼似乎是錯誤的指針?
編輯
簡單來說,我的代碼流象下面這樣:
ConcurrentDictionary<string, string> MyCache = new ConcurrentDictionary<string, string>();
private List<string> GetPrimaryKeysFromDB()
{
using(var ctx = new MyDBContext())
{
List<string> results = ctx.MyTable.Select(x=>x.PrimeColumn).ToList();
return results;
}
}
private void SomeMethod()
{
List<string> ListOfPrimeItems = GetPrimaryKeysFromDB();
Parallel.Foreach(ListOfPrimeItems, #MaxDopSetting#, k =>
{
ProcessDataForKey(k);
});
}
private void ProcessDataForKey(string key)
{
// Goto DB and fetch record for key
// Each column (Entity data member) will undergo some processing here
// some string manipulations
// Finally convert the new state of data to XML (serialize) and store in cache
MyCache[key] = TranslatedStateOfData;
}
不要這樣做。如果你的數據庫太慢,使得它更快,緩存層是如此的90年代。除此之外,請查看ParallelOptions.MaxDegreeofParallelism,將其設置爲您擁有的核心數量或最多加倍。 – Ben
謝謝你的迴應。但是,我需要轉換數據的高/快速可用性(即高速緩存)。不是最推薦的默認MaxDOP設置之一來源:[link](https://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v = vs.110).aspx) –
您需要更多信息來調試此類問題。當它「爬行」時,你的代碼中的任何代碼(而不是.NET框架)在那一刻執行?你有沒有[最小,完整和可驗證的代碼](http://stackoverflow.com/help/mcve)供我們試用?通常這樣的抓取是2件事的結果:[Thrashing](https://en.wikipedia.org/wiki/Thrashing_(computer_science))或等待/同步 – Vikhram