almost 5 years ago

前言

今天我在 DigitalOcean 的512MB RAM的VPS上
想要 gem install bundler,一直安裝失敗,看錯誤內容是寫

There is insufficient memory for the Java Runtime Environment to continue.
Native memory allocation (malloc) failed to allocate 524288 bytes for committing reserved memory.

應該是RAM不夠用了,JVM想要Allocate 512MB的RAM,但是硬體上不敷使用,因此想藉由啟用虛擬記憶體來解決此問題

如果你跟我一樣是用 DigitalOcean VPS 的話
預設是不會有配置任何Swap的,其他VPS我不清楚,但我猜應該預設都沒有啟用Swap,畢竟讀寫頻繁會增加他們固態硬碟的負擔啊!這樣的結果就是,當你的512MB的RAM不夠用時,你的程式就無法執行。

為什麼不直接升級到1GB或2GB的RAM? 因為我的伺服器同時正在跑一個Node.js的App,而且Google分析顯示線上人數有數百人,升級要先關機1~2分鐘才能處理完成,不敢冒然關機而且小氣不想加錢的狀況下使用了Swap來解決。

確認是否已啟用swap

首先,先確認你有沒有啟用Swap,你可以在 terminal 執行

free -m

應該就可以看到類似以下的內容

         total       used       free     shared    buffers     cached
Mem:           490        484          6          0         17        284
-/+ buffers/cache:        182        307
Swap:            0          0          0

如果你的Swap,total的部分是0,像上面那樣,那代表你沒有啟用swap。若有,本篇教學就失效,請停止操作。

設定 Swap File

下面的指令,我們把Swap file建立在 /var/swapfile
通常如果你是安裝在電腦上,Swap會放在不同的磁碟分割區,不過這裡我們是用VPS
不能做磁碟分割的動作,因此我們建立在同一個分割中。

現在要決定你的 Swap 大小。通常,Swap大小會是1~2倍RAM的大小,也就是虛擬記憶體大小
例如我的VPS是512MB RAM,那我就設定為兩倍,也就是1GB。
(註:DigitalOcean的512 RAM其實是指MiB,實際可用約490MB,不過不管了)

接下來的所有指令都要sudo權限,因此我們先用su比較方便

sudo su #輸入密碼

cd /var
fallocate -l 1G swapfile
chmod 600 swapfile

這樣一來,我就有一個1GB的Swap file了。
最後一行的 chmod 指令非常重要,我們要確保這個 swapfile 只能被 root 讀寫。否則會有嚴重的安全性問題。

接下來我們就能啟用swap了

mkswap /var/swapfile
swapon /var/swapfile

查看swap的狀態,確定啟用了

swapon -s

如果你有看到你的 /var/swapfile 那麼你就大功告成了。
但是,你會發現重新開機後沒作用了。

讓 Swap file 重開機後也能自動啟動

我們要在/etc/fstab檔下方新增一個指示,讓系統開機時自動啟用 swap。
執行下方語法來新增。

注意:請確定你跟我一樣是裝在/var/swapfile,不然請自行修改正確的路徑,否則將會無法開機

echo "/var/swapfile    none    swap    sw    0    0" >> /etc/fstab

微調設定

基本上,到這邊已經設定完成了。但如果你在乎效能,請繼續看下去
我當時設定到這邊,就直接開始安裝,而且沒有發生記憶體不足的錯誤了。
但是我當時有開另外一個ssh視窗 ,用htop監看RAM和Swap的使用量,結果發現
RAM明明還很多(還有150mb左右),卻就開始用Swap了。

這有什麼問題?
要知道 Swap File就是當你RAM不夠用時,就改用硬碟來當作RAM。
硬碟的存取速度遠低於RAM,即使是固態硬碟,還是比RAM慢很多,這樣會讓你的程式效能降低
而且明明RAM還撐得住,為什麼要選擇速度慢很多的硬碟呢?

調整 swappiness

swappiness 參數是一個介於0~100的數值,當數值越接近100,代表系統越積極使用Swap,當數值越接近0,系統將會盡量使用RAM。預設值是 60

你可以用下面的指令來看現在的設定

cat /proc/sys/vm/swappiness

我這裡看到是60。
對VPS而言,這不是一台一般使用者用的桌面電腦,因此我們能用時盡量榨乾RAM會比較好,畢竟硬碟效能比較差
我們應該把它調整到較低的數字,這裡我把它調整到10。

sysctl vm.swappiness=10

同樣,如果要讓他重開機後也能生效,我們要修改sysctl.conf設定檔。

echo "vm.swappiness = 10" >> /etc/sysctl.conf

這樣就完成囉!

node.js v0.10.x localeCompare sensitivity: base的問題 →
 
comments powered by Disqus