有些東西會吃掉所有記憶體(我懷疑某些應用程序存在記憶體洩漏)。如何檢測什麼?
我有執行liquidsoap+icecast 捆綁包和簡單網站(httpd+mysqld)的伺服器。沒什麼特別的。每天約有 2000 多名訪客,平均約有 50 人同時線上。
伺服器有 8GB 記憶體。隨著時間的推移,可用記憶體量不斷減少,儘管伺服器上沒有啟動任何新內容,也沒有新使用者。在某些時候它開始交換,伺服器上的負載上升並且它變得無響應。通常我所做的只是重新啟動伺服器……
可以做些什麼來檢測究竟是什麼洩漏了記憶體?我使用 top 來監控資源的使用情況,但據我所知,它沒有任何幫助:
有什麼辦法可以找出是什麼佔用了這麼多記憶體?或者什麼開始大量交換到磁碟?有什麼方法可以在不重新啟動伺服器的情況下釋放記憶體?
以批處理模式執行
top
以定期報告記憶體大小可用於查看誰在使用記憶體。在批處理sar
模式下執行應該對記憶體使用和相關 I/O 提供一些良好的診斷。執行munin
以監視系統應該會給您一個圖表,其中包含有關正在使用的記憶體的詳細資訊。這可能有很大幫助。您可以使用 limits.conf 來限製程序的最大核心大小。正確設置,這應該會殺死所有洩漏記憶體的程序。這適用於 pam_limits 模組。也可以使用
ulimits
命令設置限制。您正在執行一些可能會使用大量記憶體的程序。您可以查看的一些內容包括。
- 執行不良的應用程序
apache2
可能會洩漏記憶體。發生這種情況時,您應該會看到記憶體大小增加。MaxRequestsPerChild
您可以通過設置為 100 左右來調整 apache2 以在使用一定次數後回收孩子。如果這解決了問題,那麼您需要解決洩漏問題。我會先看這個。- MySQL 可能會嘗試將數據載入到記憶體中。如果您在記憶體中有大量數據,這可能會導致一些抖動,但不應像您看到的那樣劇烈。
- 如果你
tmpfs
掛載了一個大文件系統,那麼如果文件在使用時沒有被刪除,你可能會洩漏記憶體。大的長壽命文件也可能是一個問題。- 如果問題發生在一天中的大致相同時間,您可能有一個計劃的程序正在洩漏記憶體。
- 如果你有一個程序分配了共享記憶體,但在退出前沒有釋放它,你就會有一個相對不可見的記憶體洩漏。如果共享記憶體被鎖定在記憶體中,那麼它可能會強制交換。可用共享記憶體的數量通常相對有限。
- Liquidsoap+icecast 捆綁包可能會遇到使用記憶體的緩衝問題。我沒有使用過這種組合,所以我不確定它會如何出現。
正常記憶體使用:空閒記憶體不是你想要的。如果您的系統已經執行了很長時間並且有很多可用記憶體,那麼就會出現問題。每次讀取或寫入文件時,塊都會進入緩衝區記憶體。這會減少你的空閒記憶體,是一件好事。系統將保留足夠的可用空間來啟動一些程序,而無需在其他地方尋找記憶體。由於許多程序執行速度很快,當它們停止執行時,它們的記憶體將返回到空閒池中。
當您讀取緩衝區高速記憶體中的文件時,不需要磁碟訪問,讀取是從緩衝區高速記憶體中解析的。寫入使用類似的機制。如果您的系統需要記憶體,緩衝區記憶體是最先使用的地方之一。大多數緩衝區可以立即釋放。
如果您有記憶體洩漏,您將看到可用記憶體和緩衝區都開始縮小。這仍然不是一個嚴重的問題,因為洩漏的記憶體最終應該被移動到交換空間。您的系統仍然可以正常執行,直到您填滿交換空間,並將剩餘的可用空間減少到程序無法啟動的程度。通常會使用少量的交換空間。