1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

Linuxシステム診断 - メモリの基礎知識 徹底解説

2022-02-07 08:18:38

1. 背景

linuxのメモリに関しては、多くの場合、free, topなどの基本的なコマンドに注目します。システムが異常事態に遭遇したとき、メモリ問題の根本原因をたどり、その場で診断する場合、深いデバッグ能力が欠けています。このスペースは、深い議論をするためのものではありません。現在のシステムの問題を明確に記述できることは、SREが持つべき最も基本的な能力である。

2.無料

2.1 フリーコマンドの原理

free は /proc/meminfo を見て、どれだけのメモリが使用されているかを調べます。しかし、/proc/meminfo ファイルはどこから来るのでしょうか?procディレクトリを見てみましょう。

  • /proc は仮想ファイルシステムであり、そのディレクトリ内のファイルはすべてメモリ上にのみ存在し、スペースを取らない疑似ファイルです - du -sh を使って、そのダイパス下のディスクフットプリントがすべて 0 であることを確認してください。
  • proc以下のすべてのファイルは、カーネルがproc_create()インターフェイスを呼び出すことによって作成される仮想エントリです。
  • procのファイルは、主にシステム情報(プロセス、メモリ、CPU、デバイス情報など)をリアルタイムにフィードバックします。

結論 /proc/meminfo は、/proc ファイルシステム下の擬似ファイルであり、メモリ関連の情報を保持します。

2.2 コマンド出力入門

出力はディストリビューションによって多少異なりますので、ここでは debian8 4.19.x ディストリビューションを例にして説明します。

bool a=255; 


bool b= 254;



コマンド出力のほとんどは、解析はmanドキュメントを見ればわかるということなので、ここでは触れないことにします。

  • used: 使用メモリ使用量 = total - free -buffers -cached
  • free: 未使用メモリ memFree & /proc/meminfo の swapFree
  • shared: /proc/meminfo の tmpfs shmem で使用されるメモリ
  • buffers: カーネルが使用するためにバッファリングされたメモリ
  • cached: ページキャッシュとスラブで使用するメモリ
  • buffers/cache: バッファとキャッシュの合計を表します。
  • スワップ:スワップパーティションの使用量

2.3 バッファやキャッシュはメモリを消費しますか?

答えはイエスです。そこで、まずバッファとキャッシュについて理解しましょう。

  • キャッシュの正式な定義は、高速デバイスと低速デバイスのアクセス速度の不一致を補償することによって、リソースへのアクセスを高速化するために確保された空間のセクションである。簡単に言うと、読み出しが速くなる。
  • buffer (バッファ) は、コンピュータが多数の "小規模 IOs" に遭遇し、少数の "大規模 IOs" に整形して書き込み回数を減らす、リソース書き込み整形を行うように設計されています。これにより、書き込みリソースを適切に使用することができます。

ただし、freeコマンドで示されるバッファとキャッシュはやや狭義で、freeで示されるバッファはブロックデバイスが占有するキャッシュ、freeで示されるキャッシュは通常ファイルが占有するページキャッシュを指す。

要するに、バッファもキャッシュもLinuxの読み書き性能を高速化するためにメモリを使用し、新しいプロセスがメモリを必要とする場合、システムはバッファとキャッシュが占有しているメモリを回収し、プロセスが使用できるように再割り当てします。

2.4 その他のメモリ概念

RSS &; VSZ &; PSS &; USS

  • RSS (Resident Set Size): sharedMemを含む、プロセスで使用される物理メモリの実際のサイズです。
  • VSZ(Virtual Memory Size): ページブレークの欠落によりスワップアウトされたメモリとsharedMemを含む、プロセスがアクセスできるすべてのメモリのサイズ。
  • PSS(Proportional Set Size): メモリのサイズに比例してRSSに追加します。
  • USS(Unique Set Size): プロセス専用の物理メモリのサイズ。

usedMemはactive & inactiveに分けられます。

  • active: メモリのこの部分が特定のプロセスによって使用されており、再利用される可能性がないことを示します。
  • inactive: このメモリが実行されていないプロセスに割り当てられていることを示し、再要求される可能性が高いことを示します。

Linux は、アクティブなページと非アクティブなページのリサイクルを管理するために、LRU リストを維持します。簡単に言うと、リストの末尾に近いほどページがリサイクルされる可能性が高く、逆に列の先頭に近いほどリサイクルされる可能性は低くなります。linuxカーネルはアクティブリストと非アクティブリストの2種類のLRUListを保持しており、ちょうど訪問されたページはアクティブリストに、長い間訪問されていないページは非アクティブリストに入れられ、カーネルスレッドkswapdはアクティブリストにあるページを定期的に非アクティブリストに移動させる。

システムの非アクティブメモリが大きすぎる場合、以下の方法でリサイクルすることができます。
sync; echo 3 > /proc/sys/vm/drop_caches

3. 仮想メモリ

Linuxは仮想メモリの仕組みとリアルモードの仕組みの両方をサポートしています。

リアルモードでは、コンピュータは直接物理メモリを要求しますが、仮想メモリ機構では、システムはディスクをメモリの拡張として扱い、利用可能なメモリサイズを増加させました。そして、マッピングマップのメカニズムを通じて、物理メモリとの実際の対応関係を維持する。

ディスクとメモリ間でページを転送する活動をスワッピングまたはページスケジューリングと呼び、仮想メモリとして使用されるディスクパーティションをスワップと呼びます。

スワップをオンラインで追加することにより、一時的にメモリ不足を解消することができますが、一般にスワップをオンラインで直接減らすことはできず、プロセスがクラッシュする可能性が高くなります。スワップの設定方法の詳細については、5.1 スワップ関連の設定をご覧ください。

4. OOM

1. OOMとは何ですか?

Out Of Memory Killerは、Linuxのシステム保護機構で、システムがメモリ不足に陥ったときに、特定のプロセスを強制終了して、システムのクラッシュを防止するものです。このシステムは、プロセスに対するkill操作を実行するために、スコアリング・メカニズムを使用します。デフォルトのメカニズムでは、すべてのプロセスのメモリ使用量、CPU使用量などをスキャンして、スコア(悪さ)をつけ、スコアが高いほど、殺すべきプロセスの優先順位が高くなるようになっています。

2. システムがプロセスに点数をつけるのは、どのような動作によるものですか?

  • fork(2) 呼び出しで多数の子プロセスを生成した場合、 プロセスはスコア (+) となります。
  • プロセスが長時間稼働していたり、CPU時間を多く使っている場合は減点される(-)
  • ナイスバリューが低いプロセスには、ポイントを加算する(+)。
  • 優遇されている工程は点数が低い(-)。
  • ハードウェアデバイスに直接アクセスできるプロセスは、スコアが低くなります (-)

3. プロセスの採点はどこで見ることができますか?

/proc/<pid>/oom_score

4. スコアを手動で調整する

/proc//oom_adj このファイルを使って、oom が発生したときにどのプロセスを kill するか、デフォルト値 0 で -16 -- +15 の範囲内で調整することができます。  

特別な値 -17: プロセスが決して強制終了されないことを示します。

5. システムがOOMを発生させたかどうかを知るには?

/var/log/messages, /var/log/syslog システムログ, dmesg システムログ診断ツールで確認できます。

5. メモリ関連の設定

5.1 スワップ関連設定

システムパラメータを調整し、スワップパーティションのウェイトを使用するようにコンピュータに指示します。

char ch =1; or 0


bool a = (0 ! = atoi(ch)); 

オンラインでスワップパーティションサイズを増やすことにより、一時的にメモリリークやメモリ不足の例外などを制御します。

CStdioFile LogIDFile; 


char* pFileName = "Log.txt "; 


CString strtemp; 


if( LogIDFile.Open( pFileName, CFile::modeRead ))


{ 


LogIDFile.SeekToBegin(); 


LogIDFile.ReadString(strtemp); 


} 


LogIDFile.Close(); 

5.2 キャッシュ関連

LONG OldPicProc; 


LRESULT CALLBACK PicProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) 


{ 


    switch( message ) 


    { 


        case WM_RBUTTONDOWN: 


            { 


                WORD xPos = LOWORD(lParam); 


                WORD yPos = HIWORD(lParam); 


            } 


            break; 


    } 


  return CallWindowProc((WNDPROC)OldPicProc, hWnd, message, wParam, lParam); 


} 


LRESULT CALLBACK About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) 


{ 


    switch( message ) 


    { 


        case WM_INITDIALOG: 


            { 


              HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_1); 


                OldPicProc = SetWindowLong(hWnd, GWL_WNDPROC, (LONG)PicProc); 


            } 




            return TRUE; 
        case WM_COMMAND: 


            if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL ) 


            { 


                EndDialog(hDlg, LOWORD(wParam)); 


                return TRUE; 


            } 


            break; 


    } 


    return FALSE; 


} 

5.3 OOM関連

  • vm.panic_on_oom
  • oom メカニズムがトリガーされたときにカーネルパニックを引き起こすかどうか。0 はオフ(推奨)、1 はオン。カーネルパニックは、コンピュータが致命的なエラーに遭遇し、それについて何をすべきかわからないときのアクションです。Windowsのブルースクリーンに似ています。推奨される設定は0です。
  • vm.overcommit_kbytes:
  • 0 は設定されていないことを意味し、400 など他の値が設定されている場合、プロセスが要求できる最大メモリは swap+400kBytes になります。
  • vm.overcommit_ratio。
  • プロセスが使用できるメモリの最大量を定義します (パーセントモード)、デフォルトは 50 です。
  • vm.oom_kill_allocating_task (Linux 2.6.24+ でサポートされます)
  • これは、メモリ不足の場合の KILL OOM トリガータスクの有効化または無効化です。0 は無効 (デフォルト)、1 は有効を意味します。これは、デフォルトで無効になっている oom メカニズムのスイッチとして解釈することができます - oom トリガーを通常通り実行することを許可することを表します。
  • 興味のある人は、自分でprocを作成することができます。

今回の記事は、「Linuxシステム診断~メモリの基礎知識徹底解説~」です。Linuxシステム診断-メモリの基礎知識については、スクリプトハウスの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。