Linuxカーネルのメモリ管理。 ヤンデックスワークショップ

こんにちは 私の名前はRoman Gushchinです。 Yandexでは、Linuxカーネルに取り組んでいます。 少し前に、システム管理者向けにLinuxのメモリ管理サブシステムの一般的な説明、発生した問題のいくつか、およびそれらを解決する方法に関するセミナーを開催しました。 ほとんどの情報は「バニラ」Linuxカーネル(3.10)について説明していますが、その一部はYandexで使用されているカーネルに固有のものです。 このセミナーは、システム管理者だけでなく、Linuxがメモリでどのように機能するかを知りたいすべての人にとって興味深いものになる可能性が非常に高いです。







セミナーで取り上げられた主要なトピック:



カットの下には、基本的な概念と原則の開示とともに、レポートのより詳細な概要が表示されます。







メモリ管理サブシステムのタスクとそれを構成するコンポーネント



サブシステムの主なタスクは、カーネルお​​よびユーザー空間プロセスへの物理メモリの割り当て、およびすべてのメモリが占​​有されている場合の解放と再配布です。



主なコンポーネント:



X86_64プラットフォームハードウェア機能



NUMAスキームは、特定の量のメモリが各物理プロセッサに接続され、最速でアクセスできることを意味します。 他のプロセッサのメモリ領域へのアクセスははるかに遅くなります。



カーネルで物理メモリと仮想メモリはどのように記述されますか?



カーネルの物理メモリは、ノード(pg_data_t)、ゾーン(struct zone)、ページ(struct page)の3つの構造で記述されます。 各プロセスには独自の仮想メモリがあり、struct mm_struct構造体を使用して記述されます。 これらは順番に領域に分割されます(vm_area_struct構造体)。



メモリ管理API



カーネルは、__ get_free_page()、kmalloc()、kfree()、vmalloc()などの関数を使用して、メモリ管理サブシステムと対話します。 それらは、解放だけでなく、空きページ、メモリの大小のセクションの割り当てを担当します。 たとえば、リリース時に領域がゼロ化されるかどうかなど、小さな機能が異なる類似した関数のファミリがすべてあります。



ユーザープログラムは、関数mmap()、munmap()、brk()、mlock()、munlock()を使用してmmサブシステムと対話します。 カーネルに「ヒント」を与えることができるposix_fadvice()およびmadvice()関数もあります。 ただし、厳密に言えば、ヒューリスティックではそれらを考慮する必要はありません。



以前に使用したメモリを解放します(メモリ再利用)



システムは常に一定量の空きメモリ(空きプール)を維持しようとします。 したがって、メモリははるかに高速に割り当てられます。 彼女が本当に必要なときに彼女を解放する必要はありません。



常に使用されるメモリ内のページ(システムライブラリなど)は、ワーキングセットと呼ばれます。 メモリを強制的に削除すると、システム全体の速度が低下します。 システムのメモリ消費の全体的な割合は、メモリ負荷と呼ばれます。 この値は、システムのビジー状態によって大きく異なる場合があります。



システム内のすべての未割り当てメモリは、匿名メモリとファイルメモリの2つの部分に分割できます。 それらは、ファイルの各部分がファイルに対応していることを確認している最初のものについては異なり、そこにドロップできます。



モデルLRU



LRUは、最も最近使用されていないことを表します。 これは、最も長くアクセスしていないページを破棄することを示唆する抽象概念です。 Linuxで完全に実装することは不可能です。 特定のページへのアピールがあったかどうかだけがわかっています。 何らかの方法でページアクセスの頻度を追跡するために、アクティブ、非アクティブ、および強制不能リストが使用されます。 後者には、ユーザーがロックしたページが含まれますが、どのような状況でもメモリから消去されることはありません。



非アクティブリストとアクティブリストの間を移動するための明確なルールがあります。 メモリ不足の影響下で、非アクティブリストのページはメモリから消去されるか、アクティブリストに移動します。 アクティブリストのページは、長期間アクセスされていない場合、非アクティブに移動します。



監視ツール



上部のユーティリティは、システムのメモリ消費量の統計を表示します。 Vmtouchプログラム-特定のファイルのどの部分がメモリにあるかを示します。 ファイル、アクティブおよび非アクティブページの数に関する包括的な情報は、/ proc / vmstatにあります。 バディアロケータの統計は/ proc / buddyinfoにあり、スラブアロケータの統計はそれぞれ/ proc / slabinfoにあります。 断片化に関するすべての問題が完全に見える場所であるperf topを見ると便利なことがよくあります。



メモリーcgroup



Sigroupは、グループを複数のプロセスから区別し、それらを論理的に組み合わせ、合計メモリ消費を特定のプロセスに制限したいという要望から生まれました。 さらに、制限に達した場合、割り当てられたボリュームからメモリを正確に解放する必要があります。 この場合、この特定のグループに属するメモリを解放する必要があります(これはターゲットの再利用と呼ばれます)。 システムが単にメモリを使い果たし、空きプールを補充する必要がある場合-これはグローバル再利用と呼ばれます。 アカウンティングの観点から見ると、各ページは1つのグループにのみ属します。最初に読み取ったグループです。



圧縮



圧縮は、物理メモリを最適化するメカニズムです。 これについては、この記事で詳しく説明します 。 このメカニズムは、バージョン3.3からバージョン3.7まで、長い間壊れていました。 これは、強力な断片化の瞬間を伴う一部のマシンでは、2週間の操作後、すべてのプロセッサが排他的に圧縮され、有用なアクションを実行しなかったという事実に現れました。



All Articles