問題描述
當我在後台編譯軟件時,經常會發生這種情況,並且突然間一切開始變慢並最終凍結(如果我什麽都不做),因為我已經用完了RAM和交換空間。
這個問題假設我有足夠的時間和資源來打開Gnome終端,搜索我的曆史記錄,並執行一個sudo
命令。
什麽命令可以使我無需重新啟動硬盤或進行任何重新啟動?
最佳解決方案
根據我的經驗,Firefox和Chrome使用的RAM比我的前7台計算機的總和還要多。可能比這更多,但我離開了我的觀點。你應該做的第一件事就是關閉你的瀏覽器。一個命令?
killall -9 firefox google-chrome google-chrome-stable chromium-browser
我已經將最流行的瀏覽器集成到一個命令中,但顯然如果你正在運行其他的東西(或者知道你沒有使用其中的一種),隻需修改命令即可。 killall -9 ...
是重要的一點。人們確實對SIGKILL
(信號編號9)有所了解,但瀏覽器極具彈性。更重要的是,通過SIGTERM
緩慢終止將意味著瀏覽器會執行一係列清理垃圾 – 這需要一陣額外的RAM – 這在這種情況下是無法承受的。
如果您無法將其導入already-running終端或Alt
+ F2
對話框,請考慮切換至TTY。 Control
+ Alt
+ F2
會讓你到TTY2,它應該允許你登錄(雖然它可能很慢),甚至應該讓你使用類似htop
的東西來調試問題。我不認為我的內存已經耗盡,無法啟動htop
。
長期的解決方案包括購買更多的RAM,通過遠程計算機租用,或者不做你現在正在做的事情。我將把錯綜複雜的經濟爭論留給你,但一般來說,內存購買起來很便宜,但如果你隻需要突發數量,那麽每分鍾或每小時計費的VPS服務器是不錯的選擇。
次佳解決方案
在啟用了Magic System Request Key的係統上,按下Alt
+ System Request
+ f
(如果鍵盤上沒有標記,System Request
通常位於Print Screen
鍵上)將手動調用內核的內存不足殺手(oomkiller)最糟糕的內存使用過程並殺死它。如果你的時間可能比你描述的要少,而且係統即將開始(或者已經開始)抖動,那麽你可以做到這一點 – 在這種情況下,你可能並不關心被殺死的東西,隻是你結束了建立一個可用的係統。有時候這可能會導致X被殺,但現在大多數時候在選擇一個不好的過程比以前要好很多。
第三種解決方案
與其他答案相反,我建議您在執行此操作時禁用交換。盡管swap可以讓係統以可預測的方式運行,並且通常用於增加訪問磁盤的應用程序的吞吐量(通過驅逐未使用的頁麵以騰出磁盤緩存空間),在這種情況下,您的係統聽起來像是放緩了到無法使用的級別,因為太多積極使用的內存被強製驅逐掉。
我建議在執行此任務時完全禁用交換,以便out-of-memory殺手將在RAM填滿後立即執行操作。
替代方案:
-
將交換分區放入RAID1,提高交換的讀取速度
-
或者RAID0,如果你感覺有風險,但是如果你的任何一個磁盤發生故障,這將導致大量正在運行的程序。
-
-
減少並發構建作業的數量(“更多的核心=更多的速度”,我們都說,忘記它在RAM上需要線性收費)
-
這可能是雙向的,但是嘗試在內核中啟用
zswap
。這會在頁麵發送到交換之前壓縮頁麵,這可能會提供足夠的擺動空間來加快您的機器運行速度。另一方麵,它可能最終會成為阻礙其額外壓縮/解壓縮的障礙。 -
關閉優化或使用其他編譯器。優化代碼有時可能占用幾千兆字節的內存。如果你打開了LTO,你也會在鏈接階段使用大量的RAM。如果一切都失敗了,你可以嘗試使用lighter-weight編譯器(例如
tcc
)編譯你的項目,代價是編譯後產品的運行時性能略有下降。 (如果您為了開發/調試的目的而這樣做,通常這是可以接受的。)
第四種方案
您可以使用以下命令(如果需要,重複使用)來使用係統上最多的RAM來終止進程:
ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9
附:
-
ps -eo pid --no-headers --sort=-%mem
:顯示所有正在運行的進程的進程ID,按內存使用情況排序 -
head -1
:隻保留第一行(使用最多內存的進程) -
xargs kill -9
:殺死進程
德米特裏的準確評論後編輯:
這是一個快速且肮髒的解決方案,應在沒有敏感任務運行時執行(您不需要kill -9
的任務)。
第五種方案
this happens pretty often to me when I am compiling software in the background
在這種情況下,就像“killall -9 make”(或者任何你用來管理你的編譯的東西,如果沒有的話)。這將停止編譯進一步進行,SIGHUP將SIGHUP從它啟動的所有編譯器進程(希望導致它們停止),作為獎勵,不需要sudo,假設您編譯為與您登錄的用戶相同的用戶作為。而且,由於它會殺死問題的實際原因,而不是您的Web瀏覽器,X會話或一些隨機過程,它不會幹擾您當時在係統上執行的任何其他操作。
第六種方案
在運行資源消耗命令之前,還可以使用setrlimit(2)係統調用,可能與Bash shell的ulimit
內建(或zsh中的limit
內置),特別是-v
的RLIMIT_AS
。那麽太大的虛擬地址空間消耗(例如malloc(3)使用的mmap(2)或sbrk(2))將會失敗(errno(3)為ENOMEM
)。
然後,他們(即鍵入ulimit
後shell中的饑餓進程)將在凍結係統之前終止。
另請閱讀Linux Ate My RAM並考慮禁用memory overcommitment(通過以root身份運行命令echo 0 > /proc/sys/vm/overcommit_memory
,請參閱proc(5) …)。
第七種方案
為自己創建更多的交換。
以下將添加8G的交換:
dd if=/dev/zero of=/root/moreswap bs=1M count=8192
mkswap /root/moreswap
swapon /root/moreswap
它仍然很慢(你正在交換),但你不應該真的用完。現代版本的Linux可以交換文件。現在關於交換分區的唯一用途是用於休眠筆記本電腦。
第八種方案
在短時間內獲得大量可用RAM的一種方法是使用我如何使用zRam?,它創建一個壓縮的RAM磁盤並在那裏交換。使用任何half-decent CPU,這比普通交換快得多,並且壓縮率非常高,許多現代RAM大量web瀏覽器。
假設你已經安裝和配置了zram,你所要做的就是運行
sudo service zramswap start
第九種方案
另一個可以做的事情是通過這個命令釋放內存頁麵緩存:
echo 3 | sudo tee /proc/sys/vm/drop_caches
從kernel.org文檔(重點添加):
drop_caches
Writing to this will cause the kernel to drop clean caches, as well as reclaimable slab objects like dentries and inodes. Once dropped, their memory becomes free.
To free pagecache: echo 1 > /proc/sys/vm/drop_caches To free reclaimable slab objects (includes dentries and inodes): echo 2 > /proc/sys/vm/drop_caches To free slab objects and pagecache: echo 3 > /proc/sys/vm/drop_caches
This is a non-destructive operation and will not free any dirty objects. To increase the number of objects freed by this operation, the user may run `sync’ prior to writing to /proc/sys/vm/drop_caches. This will minimize the number of dirty objects on the system and create more candidates to be dropped.
第十種方案
sudo swapoff -a
將禁用交換,如果係統內存不足,內核將自動使用highest score中止進程。如果我知道我將運行一些RAM-heavy,如果它失控,我寧願殺死它,而不是讓它進入交換並永久卡住,我會使用它。之後使用sudo swapon -a
到re-enable。
稍後,您可能需要查看交換設置。聽起來你的交換與根分區在同一個磁盤上,當你點擊交換時會降低你的係統速度,所以如果可以的話,就避免這種情況。另外,在我看來,現代係統通常會配置太多的交換。 32GiB RAM通常意味著默認分配32GiB交換,就好像您真的想將32GiB放入交換空間一樣。
參考資料