1. 程式人生 > >解決伺服器上 w3wp.exe 和 sqlservr.exe 的記憶體佔用率居高不下的方案

解決伺服器上 w3wp.exe 和 sqlservr.exe 的記憶體佔用率居高不下的方案

SQL Server是如何使用記憶體

最大的開銷一般是用於資料快取,如果記憶體足夠,它會把用過的資料和覺得你會用到的資料統統扔到記憶體中,直到記憶體不足的時候,才把命中率低的資料給清掉。所以一般我們在看statistics io的時候,看到的physics read都是0。其次就是查詢的開銷,一般地說,hash join是會帶來比較大的記憶體開銷的,而merge join和nested loop的開銷比較小,還有排序和中間表、遊標也是會有比較大的開銷。最後我們來看查詢的開銷,這個開銷顯然是越低越好,因為我們不能從中得到好處,相反,使用了越多的記憶體多半意味著查詢速度的降低。所以我們一般要避免中間表和遊標的使用,在經常作關聯和排序的列上建立索引。

我們先來看資料快取對效能的影響,如果系統中沒有其它應用程式來爭奪記憶體,資料快取一般是越多越好,甚至有些時候我們會強行把一些資料儲存在快取記憶體中。伺服器如果還有其它應用程式,雖然在需要的時候MS SQL會釋放記憶體,但是執行緒切換、IO等待這些工作也是需要時間的,所以就會造成效能的降低。sqlservr.exe 是很吃記憶體的,如果不控制的話,他會佔光所有的實體記憶體,這樣我們就必須設定MS SQL的最大記憶體使用。

降低 sqlservr.exe 記憶體佔用率的解決方案:

1、一般情況下都是SQL語句優化的不夠好,或者快取方案使用不當造成,建議儘可能優化SQL語句以及使用合理的快取方案。

2、優化網站程式,少用或不用session、cache、application之類的快取方案,還有就是翻頁處理不好也是會佔很多記憶體。

3、設定最大伺服器記憶體:開啟SQL Server Management Studio,右鍵伺服器SQL Server -> 屬性 -> 記憶體 -> 設定最大伺服器記憶體,這個可根據伺服器配置以及需求而定,本例以2G記憶體為例,設定為實體記憶體的60%。

如果記憶體大於或者等於4G的,我一般這麼設定(總記憶體單位為GB):

初始值=(總記憶體-(總記憶體/8)-2)*1024 EXEC sys.sp_configure N'max server memory (MB)', N'初始值' GO RECONFIGURE WITH OVERRIDE GO 先預留1GB給OS 4~16GB RAM,則每4GB留1GB, 16GB RAM+,則每8GB留1GB 然後根據Memory\Available Mbytes的值(建議在300MB左右),再逐漸調高MAX Memory Value。

 限制伺服器記憶體後報錯

程式報錯:資源池 'default' 沒有足夠的系統記憶體來執行此查詢

可以嘗試通過更新資料庫的統計表資訊解決,執行以下的SQL語句即可:

EXEC sp_updatestats

簡單理解IIS應用程式池

w3wp.exe是一個IIS程序,在IIS6下,經常出現w3wp.exe的記憶體及CPU佔用不能及時釋放,從而導致伺服器響應速度很慢。

IIS的程式池預設回收間隔是1740分鐘(29小時),在自動回收過程中,應用程式池將會清空,保留在記憶體中的資料將會被清理(相當於IIS重啟)。對於網際網路應用程式,為了減少資料庫伺服器的負擔,也許會選擇將大量資料暫存在記憶體中,回收會造成記憶體資料丟失,如果沒有及時儲存到資料庫中,可能導致應用程式出問題。如果遇到系統使用高峰期,回收將可能導致一段時間應用程式無響應(出現假死狀態),給予使用者一種很不好的體驗。

在優化應用程式池之前,我們應用先了解下程式池的幾個配置資訊:

發生配置更改時禁止回收:如果為True,應用程式池在發生配置更改時將不會回收。 固定時間間隔(分鐘):超過設定的時間後,應用程式池回收,為0意味著應用程式池不會按固定間隔回收。系統預設設定的時間是1740分鐘(29小時)。禁用重疊回收:如果為true,將發生應用程式池回收,以便在建立另一個工作程序之前退出現有工作程序。 請求限制:應用程式池在回收之前可以處理的最大請求數。如果值為0,則表示應用程式池可以處理的請求數沒有限制。 生成回收事件日誌條目:每發生一次指定的回收事件時便產生一個事件日誌條目,裡面的明細設定不一一介紹。

問題分析:每1740分鐘(29小時)回收一次是否合理?

不太合理,這個週期內,有可能應用程式處於訪問高峰期。因為每天的回收時間都是不一樣的,很有可能在高峰期回收,就會造成短時間內網站訪問出現問題。因此,要避免最大程度的減少對使用者的影響,我們需要充分的分析應用程式的訪問情況,例如哪個時間段是高峰,

哪個時間段訪問人數最少。瞭解到這些後,應用程式部署人員就應該設定固定的回收時間,例如一個網站凌晨兩點訪問人數是最少的,那麼它可以設定“特定回收時間”在凌晨兩點,應用程式池裡面的特定時間是支援設定多個的,請注意。 

降低 w3wp.exe 記憶體佔用率的解決方案

開啟IIS服務管理器 -> 應用程式池 -> 選擇網站對應的應用程式池 -> 點選“正在回收” 

在彈出的視窗設定特定回收時間(在此之前右鍵網站應用程式池,選擇高階設定,將其固定時間間隔(分鐘)設定為0),並設定基於記憶體的最大值,如下圖所示:

解決CPU佔用過多

1、在IIS中對每個網站進行單獨的應用程式池配置。即互相之間不影響。 2、在工作管理員中增加顯示PID欄位。就可以看到佔用記憶體或者CPU最高的程序PID 3、在命令提示符下執行iisapp -a。注意,第一次執行,會提示沒有js支援,點選確定。然後再次執行就可以了。這樣就可以看到PID對應的應用程式池。(iisapp實際上是存放在C:\windows\system32目錄下的一個VBS指令碼,全名為iisapp.vbs,如果你和我一樣,也禁止了Vbs預設關聯程式,那麼就需要手動到該目錄,先擇開啟方式,然後選“Microsoft (r) Windows Based Script Host”來執行,就可以得到PID與應用程式池的對應關係。) 4、到IIS中察看該應用程式池對應的網站,就ok了,做出上面的記憶體或CPU方面的限制,或檢查程式有無死迴圈之類的問題。

5、找出最消耗CPU的SQL語句進行優化

-- 找出前50最耗CPU的SQL語法 SELECT TOP 50 qs.total_worker_time/qs.execution_count as [Avg CPU Time], SUBSTRING(qt.text,qs.statement_start_offset/2, (case when qs.statement_end_offset = -1 then len(convert(nvarchar(max), qt.text)) * 2 else qs.statement_end_offset end -qs.statement_start_offset)/2) as query_text, qt.dbid, dbname=db_name(qt.dbid), qt.objectid FROM sys.dm_exec_query_stats qs cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt ORDER BY [Avg CPU Time] DESC