VPSでプログラム動かしたらメモリリーク起こしていたので対策を調査&実施しました

Pythonのプログラムを使って日々自動実行していたら急に動かなくなってしまい…。素人なので原因がわかっていませんでしたが、メモリリークを起こして動かなくなっていた模様。

プログラムに利用済みの変数をクリアする処理を入れたりしましたが、サーバのメモリを明示的にクリアするプログラムを仕込んでおけば更に良いのではないかと思い調査&実行してみました。

なお、全てrootユーザで行っています。OSはCentOS7です。

free

まずは状況の確認を。メモリの空き容量を調べるfreeコマンドを使います。
オプションmはMB単位での表示にするためのもの。

free -m

VPS(TIME4VPSの最安構成)で実行した結果

total used free shared buff/cache available
Mem: 2048 382 1286 0 378 1475
Swap: 0 0 0

このVPSは2GBの物理メモリなので2048MBが返ってきます。空きは1.3GBくらいあるのでこの状態なら問題ないですね。
物理メモリに十分な空きがあるので、スワップは使われていません。

一方、512MBの物理メモリを積むVPS(Conohaの最安構成)での結果は以下の通り。結構ギリです。スワップ領域も使っています。

total used free shared buff/cache available
Mem: 487 60 183 0 243 394
Swap: 2047 179 1868

Conohaの方は放っておくとメモリがパンパンになりそうです。

sync

syncコマンドは物理メモリのキャッシュをディスクに書き込むコマンドだそう。
私の環境でやってみたものの、前後にfreeで確認してもあまり変化はなかったので、使わなくていいんじゃないかな?(適当)

drop_caches

さて本題。

drop_cachesを実行するとキャッシュがクリアされるとのこと。コマンドは以下の通り。

echo 3 > /proc/sys/vm/drop_caches

3の部分はオプションで、1~3を入れられるそうだけど、ページキャッシュとSlabキャッシュすべてをクリアするためには3を指定するらしいので、3にしました。(Slabってなんや…ってレベルですが、私は)

Conohaで実行してみます。

# free -m
total used free shared buff/cache available
Mem: 487 106 142 1 238 348
Swap: 2047 185 1862

# echo 3 > /proc/sys/vm/drop_caches

# free -m
total used free shared buff/cache available
Mem: 487 89 340 1 56 364
Swap: 2047 185 1862

お~、これは効果的。キャッシュがクリアされたことがわかりました。

一方、Time4VPSの方はと言うと、やってみたものの効果が見られなかったので割愛。まだ余裕があるから?

ちなみに、Time4VPSの方はルートユーザーで操作しているのに、コマンド内にsudoをかませる必要がありました。

echo 3 > sudo /proc/sys/vm/drop_caches

swapoff && swapon

スワップ領域をクリアするにはスワップを無効→有効にすればよいとのこと。オプションaはすべてのスワップ領域(all)を対象にする。

swapoff -a

swapon -a

ただ、続けて実行するのであれば&&でつなげればOK

swapoff -a && swapon -a

ConohaのVPSで試した結果。Swapの利用領域がクリアされました。その代わり、物理メモリの利用領域が増えましたね。

# free -m
total used free shared buff/cache available
Mem: 487 57 224 1 204 396
Swap: 2047 184 1863

# swapoff -a && swapon -a

# free -m
total used free shared buff/cache available
Mem: 487 207 50 24 229 222
Swap: 2047 0 2047

シェルを作って動かす

コマンドを確認したので、それらをまとめて実行したいと思います。

memory_release.sh

#!/bin/bash
echo 3 > sudo /proc/sys/vm/drop_caches
swapoff -a && swapon -a

TIME4VPSで実行した結果。

# free -m
total used free shared buff/cache available
Mem: 2048 456 1464 0 126 1435
Swap: 0 0 0

# bash memory_release.sh

# free -m
total used free shared buff/cache available
Mem: 2048 382 1541 0 123 1512
Swap: 0 0 0

Conohaでこうした結果。

# free -m
total used free shared buff/cache available
Mem: 487 76 162 1 248 377
Swap: 2047 183 1864

# bash memory_release.sh > out.log

# free -m
total used free shared buff/cache available
Mem: 487 228 10 24 248 202
Swap: 2047 0 2047

あれ?増えてる。スワップをオフオンしたことでスワップ領域のデータが物理メモリに渡されたのか?

Conohaの方はスワップの方はあまりいじらないほうがいいかも。ということで、drop_cachesのみにしておきます。

memory_release.sh (Conoha)

#!/bin/bash
echo 3 > sudo /proc/sys/vm/drop_caches

cronでシェルを自動実行

いちいちシェルを実行するのも面倒なので、cronに設定して定期的に自動実行させます。

memory_release.shのパーミッションは755にしておきます。

夜中の3時に設定

0 3 * * * /usr/bin/bash memory_release.sh

ちなみにTIME4VPSは6時間の時差があるので、21時に設定をしておきます。

0 21 * * * /usr/bin/bash memory_release.sh

以上!とりあえずこれで様子を見ます。