2016-11-15 127 views
1

我想在ASP.NET MVC(5)應用程序中獲得關於內存管理的更多信息。MVC應用程序內存管理

爲了簡單起見,讓我們說,我們有角控制器,它不僅使一個http.get()電話對我api controller檢索70 000件IEnumerable<CustomItem>,之後將結果輸出到頁面(頁面實現一個簡單的頁面)。

查看我的診斷工具(內存分析器)時,可以看到內存從50 MB(起始點)上升到300 MB(一旦檢索到所有數據)。

這裏是我不明白的事情:
爲什麼當我打開不同的瀏覽器相同的頁面在同一時間(試圖模擬更多的用戶在同一時間訪問該頁面),該第二個用戶的內存消耗不會再增加250 MB,但即使數據已被再次加載,它仍保持不變?

我在印象中,ApiController不是在用戶之間共享,而是爲每個用戶創建新實例。如果我是對的,情況確實如此,那麼如果再有70 000件物品到達內存消費沒有改變?

任何文章或解釋將不勝感激。

加成1:
我的API控制器被從SharePoint rerieving數據,因此我必須所有70項000記錄在一次傳遞給我的角分量,從而事後實現分頁。換句話說,我的組件只加載一次所有數據(70 000條記錄),之後只顯示一部分(否則,如果我在瀏覽器用於凍結的70 000個項目上使用了data-ng-repeat)。

如果必要的話我一定能顯示我ApiController代碼,但實際上它的代碼只是3線,返回IEnumerable<CustomItem>僅容納三個字符串屬性。這是它的樣子:

public class SharepointFile 
{ 
    public string FileType { get; set; } 
    public string FileName { get; set; } 
    public string FilePath { get; set; } 
} 
+1

您使用的數據庫是?你的控制器源代碼是什麼樣的?記錄的平均大小是多少?很難說這裏發生了什麼。大部分的內存使用可能是應用程序本身,而不是數據,但我不確定。 –

+1

需要更多信息,您是否將所有記錄加載到內存中?如果分頁是以正確的方式實現的(數據庫端),那麼你從來沒有真正擁有'IEnumerable '上的70K記錄,你只需要顯示(當前頁面),並且這不會代表高負載服務器。 – JOBG

+0

從你扔的數字看來,你正在將所有70k記錄加載到內存中。對於單個分頁查詢,內存不應該增加太多。 – user449689

回答

0

您看到的內存上升是進程使用的實際內存。但是如果內存不受先前執行的請求的影響,.NET可能不會分配更多內存,儘管所有對象都將被垃圾回收並將被新分配,但.NET可能不需要更多內存。除非操作系統告知進程,否則通常進程不會釋放內存。他們繼續使用內存空間。

每次請求後不必要的釋放內存將需要大量的CPU使用,它會在操作系統級別在內存中創建大量的碎片。

活動.NET對象的總大小和爲它們保留的內存之間總是有區別的。

因此,對於第二個請求,所有70k對象不共享,但它們是新的,但進程已經有空的空間來存儲它們,所以它不會從操作系統請求更多的內存。

+0

這是真的嗎?在這種情況下,我怎麼能告訴我的程序把內存回給操作系統? – user230910

0

你可以讓你的ApiController在用戶之間共享,但你爲什麼要這樣做?這些mvc應用程序被設置爲無狀態,並且沒有真正需要在請求之間共享它們。

您在內存消耗中看到的內容不與內存中的具體對象匹配。

您可以隨時調整應用程序的內存使用情況,以查看正在存儲的內容以及分配的內容。您可以嘗試Ants Memory ProfilerdotTrace from JetBrains。如果你不能適應其他人的話,那麼也有很好的免費WinDbg

另請注意,內存管理主題可能會有所不同,具體取決於您如何託管您的Web應用程序。例如,在IIS中,您會發現與應用程序池的內存管理相關的大量主題。

您可以使用工具資源管理器等工具來比較工作與虛擬內存大小。