web-dev-qa-db-ja.com

CentOS、カーネル:メモリ不足

次の問題で私を助けてくれることを願っています。

CentOSリリース6.6(最終)システムでCrushFTPサービスを実行しています。しかし、ほぼ毎週、サービスがクラッシュします。

だから私はログを見て、この行を見つけました

cat /var/log/messages

Jun 28 05:06:23 crushftp kernel: Out of memory: Kill process 1491 (Java) score 883 or sacrifice child
Jun 28 05:06:23 crushftp kernel: Killed process 1491, UID 0, (Java) total-vm:9620220kB, anon-rss:3245824kB, file-rss:128kB

CrushFTPはJavaであり、マシン上で実行している唯一のサービスです。ログは、システムがプロセスを強制終了しているように見えます。

しかし、その理由はわかりません。だから私は少し検索してこの設定を見つけました

cat /proc/sys/vm/overcommit_memory
0

私がそれが正しいと理解したとき、値は大丈夫でなければならず、プロセスがさらにRAMを必要とする場合、それを取得できるはずです。

「トップ」を実行すると、Javaプロセスは、RAMの使用量が最も多いプロセスです。

top - 11:13:58 up 1 day, 4 min,  1 user,  load average: 0.93, 0.94, 0.91
Tasks:  97 total,   1 running,  96 sleeping,   0 stopped,   0 zombie
Cpu(s): 11.2%us, 19.7%sy,  0.0%ni, 68.6%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Mem:   3924136k total,  2736996k used,  1187140k free,   149380k buffers
Swap:  4128764k total,        0k used,  4128764k free,   814480k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1486 root      20   0 3633m 1.5g  13m S 20.3 39.8 191:24.36 Java

RAMは約4GBで、SWAPファイルは同じサイズです。

[root@atcrushftp ~]# cat /proc/meminfo
MemTotal:        3924136 kB
MemFree:         1159964 kB
Buffers:          149400 kB
Cached:           814476 kB
SwapCached:            0 kB
Active:          1956028 kB
Inactive:         619664 kB
Active(anon):    1611452 kB
Inactive(anon):      528 kB
Active(file):     344576 kB
Inactive(file):   619136 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4128764 kB
SwapFree:        4128764 kB
Dirty:                36 kB
Writeback:             4 kB
AnonPages:       1597696 kB
Mapped:            34108 kB
Shmem:               164 kB
Slab:             136024 kB
SReclaimable:      74432 kB
SUnreclaim:        61592 kB
KernelStack:        1384 kB
PageTables:         5948 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6090832 kB
Committed_AS:     746432 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      285216 kB
VmallocChunk:   34359441520 kB
HardwareCorrupted:     0 kB
AnonHugePages:   1501184 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       18432 kB
DirectMap2M:     4175872 kB

サポートに聞いたところ、CrushFTPのせいではなく、システムのメモリが不足しているとのことでした。

今私の質問は、どのプロセスが最後の空きメモリをすべて使用しているかをどのように見つけることができるかということです。

2
user3772108

OOM-killerログを読まなければならなかったのは久しぶりですが、覚えているように、これは

Jun 28 05:06:23 crushftp kernel: Killed process 1491, UID 0, (Java) total-vm:9620220kB, anon-rss:3245824kB, file-rss:128kB

これは、Javaが9GBのVMを使用していたときに、OOM-killerが頭を撃ったことを意味します。4GBのコアと4GBのスワップがあるとすると、それは合理的なことのように思えます。

私がそれが正しいと理解したとき、値は大丈夫でなければならず、プロセスがさらにRAMを必要とする場合、それを取得できるはずです。

わかりません。

まず、その値を0に設定しても、オーバーコミットメントはオフになりません。 Red Hatが書いているように 、これを0に設定するには、

カーネルは、使用可能なメモリの量を見積もり、明らかに無効な要求を失敗させることにより、ヒューリスティックなメモリオーバーコミット処理を実行します。残念ながら、メモリは正確なアルゴリズムではなくヒューリスティックを使用して割り当てられるため、この設定により、システムで使用可能なメモリが過負荷になる場合があります。

2に設定すると、必要に応じて次のことが実行されます。

カーネルは、使用可能なスワップの合計とovercommit_ratioで指定された物理的なRAMのパーセンテージの合計以上のメモリの要求を拒否します。この設定は、メモリのオーバーコミットのリスクを減らしたい場合に最適です。

ただし、オーバーコミットをオフにしても、プロセスが常により多くのRAMを取得できるとは限りません。無限のVMのみが保証します。コア+スワップが有限である限り、使い切ることができます。カーネルがもう少し必要になった瞬間に、すべての無料のVMを消費するプロセスがあります。その後、OOM-killerがウェイクアップし、それが起こったように見えます。

私の推奨事項は次のとおりです。

  1. Javaをrootとして実行しないでください。理想的には、まったく実行しないでください。ただし、必要な場合は、rootとして実行しないでください。それはそれにOOM-killersの目に重みを与え、代わりに何か重要なものが殺される結果になるかもしれません。

  2. Javaを使用しているものでメモリリークを見つけます。

  3. メモリリークがないと本当に信じている場合は、十分なコアがありません。より大きなサーバーのためにポニーアップ。同様に、より多くのスワップを与えます。

  4. JavaのVMフットプリントを改善し、すべてが膨張した場合は頭の中で撃ちます。

0
MadHatter