2011-02-18 45 views
16

我有一個內置在ASP.NET MVC 3中的應用程序,它使用SQL CE存儲和EF CTP 5進行數據訪問。ASP.NET MVC和EF代碼第一次內存使用

我已經將此站點部署到共享主機,只是發現它不斷被回收,因爲它達到了他們在(專用)應用程序池上設置的100mb限制。

該網站在發佈模式下運行時使用大約110MB RAM。

我試過使用SQL Server Express而不是CE,這沒什麼區別。

唯一的顯着差異是當我完全刪除EF(使用假回購)。這減少了30mb-40mb之間的內存使用量。一個空白的MVC模板使用大約20mb,所以我認爲這不是太糟糕?

「標準」ASP.NET MVC應用程序是否有任何基準?

很高興知道其他EF CTP用戶獲得的內存使用情況以及針對內存分析工具(最好是免費的)的一些建議。

值得一提的是我如何處理EF ObjectContext的生命週期。我使用的每個請求的會話和實例的ObjectContext使用StructureMap:

For<IDbContext>().HttpContextScoped().Use(ctx => new MyContext("MyConnStringName")); 

非常感謝 本

+1

海事組織,爲您的應用程序池100MB是微不足道的。 – 2011-02-18 18:45:03

+0

這就是我的想法,但直到我有東西來衡量它與我沒有真正的情況下回到主機。 – 2011-02-18 19:04:16

+0

這取決於你的支付多少。很明顯,每月10美元的共享託管公司不會爲這樣的經濟協議分配更多的資源。另一方面,如果你每月支付50美元左右,你應該得到1GB的內存,這將是很多。 – 2011-02-19 21:04:42

回答

25

我們確實設法相當顯着地減少了我們的內存佔用量。與之前的100 + MB相比,IIS工作進程現在位於50MB左右。

下面是一些可以幫助我們的東西:

  • 檢查的基礎知識。確保在發佈模式下編譯並在web.config中將編譯調試設置爲false。很容易忘記這樣的事情。
  • 使用DEBUG符號來診斷代碼。這樣做的一個例子就是使用像NHProf這樣的工具(是的,我之前被這個問題抓住了)。最簡單的方法是將這些代碼封裝在#if DEBUG指令中,以確保它不會編譯到應用程序的發行版中。
  • 不要忘記SQL。 ORM很容易忽略你的應用程序與數據庫的對話。使用SQL Profiler或EFProf/NHProf等工具可以準確地告訴你發生了什麼。在EF的情況下,你可能會感覺有點不舒服,特別是如果你大量使用延遲加載。一旦你解決了這個問題,你可以開始優化(見下文)。
  • 延遲加載很方便,但不應在MVC視圖(IMO)中使用。這是我們高內存使用率的根本原因之一。我們網站的主頁由於延遲加載(SELECT N + 1)而創建了59個單獨的查詢。在爲這個頁面創建一個特定的視圖模型並且急切地加載我們需要的關聯之後,我們就完成了一半時間內執行的6個查詢。
  • 設計模式可以指導你,而不是規定你的應用程序的開發。我傾向於在可能的情況下遵循DDD方法。在這種情況下,我真的不想在我的域模型上公開外鍵。然而,由於EF不像NH那樣處理多對一的關聯(它會發出另一個查詢來獲取我們已經擁有的對象的外鍵),所以我最終得到了一個額外的查詢(每個對象)顯示在我的頁面上。在這種情況下,我決定爲了提高性能,可以忍受一點代碼味道(包括我的模型中的FK)。
  • 一個常見的「解決方案」是在性能問題上拋出緩存。在制定緩存策略之前,確定真正的問題很重要。我本可以將輸出緩存應用到我們的主頁(請參閱下面的註釋),但這並沒有改變這個事實,即當緩存過期時,有59個查詢會觸發我的數據庫。

輸出緩存的說明: 當ASP.NET MVC首次發佈,我們能夠做甜甜圈緩存,即從一個特定區域(一個或多個)除了緩存的頁面。事實上,這不再可能使輸出緩存相當無用,如果你有頁面上的用戶特定信息。例如,我們在網站的導航菜單中擁有登錄狀態。僅此一項意味着我無法使用輸出緩存作爲頁面,因爲它也會緩存登錄狀態。

最終,如何優化應用程序並沒有硬性規定。當我們停止使用ORM構建我們的關聯(面向公衆面對我們網站的一部分)並將其手動加載到我們的視圖模型中時,我們的應用程序性能得到了最大的改善。我們不能使用EF來加載它們,因爲有太多的關聯(導致UNION查詢混亂)。

一個例子是我們的標記機制。像BlogPost和Project等實體可以被標記。標籤和可標記的實體具有多對多的關係。在我們的情況下,最好檢索所有標籤並緩存它們。然後,我們創建了一個linq投影來緩存可標記實體的關聯關鍵字(例如ProjectId/TagId)。當爲我們的頁面創建視圖模型時,我們可以爲每個可標記的實體構建標籤而不會觸及數據庫。同樣,這對我們的應用程序是特定的,但它在性能和降低內存使用方面取得了巨大的進步。

一些我們前進的道路上所使用的資源/工具:

雖然我們確實在託管公司的(Arvixe)應用程序池限制下進行了改進,但我確實有責任建議正在查看其Windows經銷商計劃的人員提供此類限制(因爲Arvixe在廣告計劃時沒有提及這一點)。所以當某些東西看起來太好以至於不真實(無限的x,y,z)時,通常是這樣。