Linuxオペレーティングシステムに十分なメモリがない場合、システムはメモリを再利用し、再利用したメモリを他のプロセスに割り当てます。 メモリの再利用でメモリ不足の問題が解決されない場合、システムはOut of memory Killer (OOM Killer) をトリガーして、プロセスによって占有されているメモリを強制的に解放します。 これは記憶圧力を軽減する。 このトピックでは、Alibaba Cloud LinuxでOOM Killerがトリガーされる問題の考えられる原因と、その問題を解決する方法について説明します。
問題の説明
次のサンプルログは、テスト
プロセスがAlibaba Cloud LinuxでOOM Killerをトリガーしたことを示しています。
565 [Sat Sep 11 12:24:42 2021] test invoked oom-killer: gfp_mask=0x62****(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null), order=0, oom_score_adj=0
566 [Sat Sep 11 12:24:42 2021] test cpuset=/ mems_allowed=0
567 [Sat Sep 11 12:24:42 2021] CPU: 1 PID: 29748 Comm: test Kdump: loaded Not tainted 4.19.91-24.1.al7.x86_64 #1
568 [Sat Sep 11 12:24:42 2021] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS e62**** 04/01/2014
考えられる原因
OOM Killerは、インスタンスまたはインスタンス内のcgroupに十分なメモリがない場合にトリガーされます。 次の表に、Alibaba Cloud LinuxでOOM Killerがトリガーされる問題の原因を示します。
原因 | シナリオ例 |
cgroupには十分なメモリがありません。 | OOM Killerが次のログに記録されているようにトリガーされるシナリオでは、OOM Killerはtest プロセスが属する /mm_test cgroupでトリガーされます。 [Wed Sep 8 18:01:32 2021] test invoked oom-killer: gfp_mask=0x240****(GFP_KERNEL), nodemask=0, order=0, oom_score_adj=0
[Wed Sep 8 18:01:32 2021] Task in /mm_test killed as a result of limit of /mm_test
[Wed Sep 8 18:01:32 2021] memory: usage 204800kB, limit 204800kB, failcnt 26
原因: /mm_test cgroupのメモリ使用量が上限の200 MBに達しました。 |
親cgroupには十分なメモリがありません。 | OOM Killerが次のログに記録されているようにトリガーされるシナリオでは、test プロセスは /mm_test/2 cgroupに属しますが、OOM Killerは /mm_test cgroupでトリガーされます。 [Fri Sep 10 16:15:14 2021] test invoked oom-killer: gfp_mask=0x240****(GFP_KERNEL), nodemask=0, order=0, oom_score_adj=0
[Fri Sep 10 16:15:14 2021] Task in /mm_test/2 killed as a result of limit of /mm_test
[Fri Sep 10 16:15:14 2021] memory: usage 204800kB, limit 204800kB, failcnt 1607
原因: /mm_test/2 cgroupのメモリ使用量は上限に達していませんが、/mm_test 親cgroupのメモリ使用量は上限の200 MBに達しています。 |
インスタンスに十分なメモリがありません。 | OOM Killerが次のログに記録されたとおりにトリガーされるシナリオでは、limit of host はインスタンスに十分なメモリがないことを示します。 ログデータでは、Node0の空きメモリ量 (free parameterの値) が空きメモリの下限 (low parameterの値) よりも小さい。 [Sat Sep 11 12:24:42 2021] test invoked oom-killer: gfp_mask=0x62****(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null), order=0,
[Sat Sep 11 12:24:42 2021] Task in /user.slice killed as a result of limit of host
[Sat Sep 11 12:24:42 2021] Node 0 DMA32 free:155160kB min:152412kB low:190512kB high:228612kB
[Sat Sep 11 12:24:42 2021] Node 0 Normal free:46592kB min:46712kB low:58388kB high:70064kB
原因: インスタンスの空きメモリ量が空きメモリの下限よりも少なく、メモリの再利用ではメモリ不足の問題を解決できません。 |
メモリノードに十分なメモリがありません。 | OOM Killerが次のログに記録されたとおりにトリガーされるシナリオでは、ログデータは次の情報を提供します。 limit of host は、メモリノードに十分なメモリがないことを示します。
インスタンスには、ノード0とノード1の2つのメモリノードがあります。 ノード1の空きメモリ量 (free パラメータの値) が空きメモリの下限 (low パラメータの値) よりも小さい。 インスタンスには大量の空きメモリ (free:4111496 ) があります。
[Sat Sep 11 09:46:24 2021] main invoked oom-killer: gfp_mask=0x62****(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null), order=0, oom_score_adj=0
[Sat Sep 11 09:46:24 2021] main cpuset=mm_cpuset mems_allowed=1
[Sat Sep 11 09:46:24 2021] Task in / killed as a result of limit of host
[Sat Sep 11 09:46:24 2021] Mem-Info:
[Sat Sep 11 09:46:24 2021] active_anon:172 inactive_anon:4518735 isolated_anon:
free:4111496 free_pcp:1 free_cma:0
[Sat Sep 11 09:46:24 2021] Node 1 Normal free:43636kB min:45148kB low:441424kB high:837700kB
[Sat Sep 11 09:46:24 2021] Node 1 Normal: 856*4kB (UME) 375*8kB (UME) 183*16kB (UME) 184*32kB (UME) 87*64kB (ME) 45*128kB (UME) 16*256kB (UME) 5*512kB (UE) 14*1024kB (UME) 0 *2048kB 0*4096kB = 47560kB
[Sat Sep 11 09:46:24 2021] Node 0 hugepages_total=360 hugepages_free=360 hugepages_surp=0 hugepages_size=1048576kB
[Sat Sep 11 09:46:24 2021] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[Sat Sep 11 09:46:24 2021] Node 1 hugepages_total=360 hugepages_free=360 hugepages_surp=0 hugepages_size=1048576kB
[Sat Sep 11 09:46:25 2021] Node 1 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
原因: NUMA (Non-Uniform Memory Access) ストレージモードでは、オペレーティングシステムに複数のメモリノードが存在する可能性があります。 cat /proc/buddyinfoコマンドを実行して、リソース情報を照会できます。 cpuset.mems インターフェイスを使用して特定のcgroupが特定のメモリノードのメモリを使用するように制限する場合、インスタンスに十分な空きメモリがある場合でも、OOM Killerがトリガーされる可能性があります。 |
バディシステムは、メモリ断片化の場合に十分なメモリを有していない。 | OOM Killerが次のログに記録されたとおりにトリガーされるシナリオでは、ログデータは次の情報を提供します。 OOM Killerは、オーダー3 の割り当てフェーズ中にオペレーティングシステムでトリガーされます。 ノード0の空きメモリ量 (free パラメータの値) が空きメモリの下限 (low パラメータの値) よりも大きい。 ノード0のバディシステムのメモリは0 (0 * 32kB (M) ) である。
[Sat Sep 11 15:22:46 2021] insmod invoked oom-killer: gfp_mask=0x60****(GFP_KERNEL), nodemask=(null), order=3, oom_score_adj=0
[Sat Sep 11 15:22:46 2021] insmod cpuset=/ mems_allowed=0
[Sat Sep 11 15:22:46 2021] Task in /user.slice killed as a result of limit of host
[Sat Sep 11 15:22:46 2021] Node 0 Normal free:23500kB min:15892kB low:19864kB high:23836kB active_anon:308kB inactive_anon:194492kB active_file:384kB inactive_file:420kB unevi ctable:0kB writepending:464kB present:917504kB managed:852784kB mlocked:0kB kernel_stack:2928kB pagetables:9188kB bounce:0kB
[Sat Sep 11 15:22:46 2021] Node 0 Normal: 1325*4kB (UME) 966*8kB (UME) 675*16kB (UME) 0*32kB (M) 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB =
原因: オペレーティングシステムがメモリを割り当てるときにバディシステムに十分なメモリがない場合、システムはOOM Killerをトリガーしてメモリを解放し、解放されたメモリをバディシステムに割り当てます。
説明 バディシステムは、Linuxのカーネルメモリ管理メカニズムであり、メモリの断片化を軽減し、さまざまなサイズのメモリブロックを効率的に割り当てて解放します。 |
解決策
シナリオに基づいて次の手順を実行し、問題をトラブルシューティングします。
cgroupまたは親cgroupに十分なメモリがありません
メモリを占有しているプロセスを評価し、不要なプロセスを終了してメモリを解放することを推奨します。 ビジネスに大量のメモリが必要で、インスタンスのインスタンスタイプがこの要件を満たしていない場合は、メモリサイズの大きいインスタンスタイプにアップグレードできます。
インスタンスのインスタンスタイプをアップグレードします。
詳細については、「インスタンス設定の変更の概要」をご参照ください。
次のコマンドを実行して、指定したcgroupのメモリの上限を調整します。
sudo bash -c 'echo <value> > /sys/fs/cgroup/memory/<cgroup_name>/memory.limit_in_bytes '
<value>
を新しいメモリの上限に置き換え、<cgroup_name>
を実際のcgroup名に置き換えます。
インスタンスに十分なメモリがありません
インスタンスに十分なメモリがない場合は、次の項目を確認してください。
slab_unreclaimableメモリの使用
cat /proc/meminfo | grep "SUnreclaim"
slab_unreclaimableメモリは、システムで再利用できないメモリです。 slab_unreclaimableメモリが全メモリの10% 以上を占める場合、システムはスラブメモリリークを有する可能性がある。 メモリリークのトラブルシューティング方法については、インスタンスのslab_unreclaimableメモリの割合が高い場合はどうすればよいですか? 問題が解決しない場合は、 チケットを起票してください。
systemdメモリの使用
cat /proc/1/status | grep "RssAnon"
OOM Killerがカーネルでトリガーされると、システムの最初のプロセス (PID 1) がスキップされます。 この場合、systemdのメモリ使用量は200 MBを超えません。 例外が発生した場合は、systemdバージョンを更新できます。
透明な巨大なページ (THP) 機能の使用法
THP機能が有効になっている場合、メモリの肥大化が発生し、OOMキラーがトリガーされます。 THPパフォーマンスを最適化できます。 詳細については、「」をご参照ください。THPを使用してAlibaba Cloud Linuxのパフォーマンスを調整する方法を教えてください。.
メモリノードに十分なメモリがありません
メモリノードのメモリが不足しているためOOMキラーがトリガーされた場合は、cpuset.mems
インターフェイスの値を再設定して、cgroupsがメモリノードのメモリを適切に使用できるようにします。
次のコマンドを実行して、システム内のメモリノードの数を照会します。
cat /proc/buddyinfo
次のコマンドを実行して、cpuset.mems
インターフェイスの値を指定します。
sudo bash -c 'echo <value> > /sys/fs/cgroup/cpuset/<cgroup_name>/cpuset.mems'
<value>
を実際のメモリノード番号に、<cgroup_name>
を実際のcgroup名に置き換えます。
例えば、インスタンスが、ノード0、ノード1、及びノード2の3つのメモリノードを有すると仮定する。 cgroupがノード0とノード2のメモリを使用できるようにするには、<value>
を0,2
に設定します。
バディシステムには十分なメモリがありません。
メモリの断片化によりOOMキラーがトリガーされた場合は、オフピーク時に定期的にメモリをデフラグします。 次のコマンドを実行して、メモリを最適化できます。
sudo bash -c 'echo 1 > /proc/sys/vm/compact_memory '